Possible mistake in contracts calculation

Fixed
L32GIT [github] · 4 years ago

Describe the issue
Let's see a problem on an example: Slag to Sour Water contract.
Raw data exported from the game source:

Quantity to pay with: 540
Quantity to buy: 218
Pay state: Loose (180 per ship module)
Buy state: Liquid (220 per ship module)

The game trading page states for 8-module ship: 1068 to 432. Which actually remains room for more goods. Correct values should have been 1080 to 436.

Your code in GetTradeEstimateForShipSize is a mess. 2 nested loops of iteration for no reason I could understand.
Let's do the different approach. Inputs are raw data and amount of modules = 8.

  1. Calculate module fill ratios for both products. They are 540/180 and 218/220 respectively.
  2. Divide them one over each other in a way we get a >1 ratio. We get 330/109. We also know here that Slag fills faster (I don't mean physical filling rates , I mean virtual "filling rate" in terms of internal contract ratio of 540/218).
  3. Add 1 to that ratio. We get 439/109. Then divide amount of modules by that new number. We get 872/439.
  4. Here, because buying product is the slower one, we ceil that number. Rule is that it's either ceil or floor, whatever gives us the most product bought. We get 2. This is an optimal amount of slower filling modules (Sour Water in our case). 6 Modules are reserved for faster filling Slag.
  5. Calculate full fill of Slag modules. 180 * 6 = 1080. Then deduce Sour Water amount from that number, using original 540/218 ratio, round it down to the next integer. If for some reason it became higher than 2 * 220, floor it to that, and recalculate Slag amount rounding up to the next integer. This should be probably decided by the same IF case from step 4, which decides if we floor or ceil there.

Algo may not be perfect and requires some edge casing in some contracts, but at least this is much faster than yours and produces a fully filled ship.

Expected behavior
1080 to 436

L32GIT [github] · 4 years ago

I get it that GetTradeEstimateForShipSize is probably used in ANY module configurations, which players actually build, therefor loops, but still the calculus is off probably because there is some bad rounding happening.

L32GIT [github] · 4 years ago

The algorithm above has flaws. I'll use this page for my notes. I care because I need this to work for the Wiki contracts calculation.

L32GIT [github] · 4 years ago

example data (inputs):
Qb = 218
Qp = 540
MSb = 220
MSp = 180
M = 8

Algo:

Rb = Qb / MSb;
Rp = Qp / MSp;

if (Rb > Rp) {
Rc = M / (Rb / Rp + 1);
Mp1 = floor(Rc);
Mb1 = M - Mp1;
Mp2 = ceil(Rc);
Mb2 = M - Mp2;
} else {
Rc = M / (Rp / Rb + 1);
Mb1 = floor(Rc);
Mp1 = M - Mb1;
Mb2 = ceil(Rc);
Mp2 = M - Mb2;
}

L32GIT [github] · 4 years ago

// check two configurations with overflow prevention and compare product amounts in both to find out final result.
// If Rc was integer, both configurations will be identical.

RQb1 = Mb1 * MSb;
RQp1 = ceil(RQb1 / Qb * Qp);
if (RQp1 > Mp1 * MSp) {
RQp1 = Mp1 * MSp;
RQb1 = floor(RQp1 / Qp * Qb);
}

RQb2 = Mb2 * MSb;
RQp2 = ceil(RQb2 / Qb * Qp);
if (RQp2 > Mp2 * MSp) {
RQp2 = Mp2 * MSp;
RQb2 = floor(RQp2 / Qp * Qb);
}

if (RQb1 > RQb2) else

Where RQb and RQp are resulting quantities of products.

Captain Filip Captain Filip · 3 years ago

Looking into the game right now the value is 1080 to 436 for 4-module ship. We have unified this calculation some time ago. So we can close this.

Closed as ✅ Fixed

6 Showing 1–6 of 6