In this optimization problem, I am trying to maximize the output value representing the "income" of a city based on some arbitrary formula. The formula relies on discrete values, so-called improvements, most of which are variables that the solver is free to play with.
My question relates to the fact that if I specifically divide the objective function so that their magnitude is smaller, it yields better results. I can confirm that because if I then take the values for the improvements (vars) and run them through the formula, I get a better result.
For the code, most of it is jargon and I think is not relevant? I will try to be succinct.
m = gekko.GEKKO(remote=False, name="Optimal Build")
m.options.SOLVER = 1
m.solver_options = ['minlp_gap_tol 1.0e-10',
'minlp_integer_tol 1.0e-10']
f = FormulasSolver(m) # Formulas, external
imps = f.improvements # Values for each improvement, ie pollution,
# base cost, prd rate, max number of improvements per imp type...
x = 27 * [0] # Array of imps
for i in imps.non_constant():
x[imps.index(i)] = m.Var(value=0, name=i.name, lb=0, ub=i.building_limit, integer=True)
for i in imps.constant():
x[imps.index(i)] = m.Const(value=constant_buildings[imps.index(i) - 23], name=i.name)
m.Equation("" Sum of all imps, max number of imps is 50 "" <= 50)
m.Equation("" Sum of commerce affecting imps, max commerce is 100% "") <= 100)
commerce = m.Intermediate("" Sum of improvements that affect commerce "") # Commerce
pollution_index = m.Intermediate("" Sum of improvements that affect pollution "") # Pollution Index
m.Maximize((
f.fixed_city_income(2500, 2500, commerce, pollution_index, 365, x[15], x[16]) # Fixed Income
- sum("" Base cost for every imp "") # Fixed Cost
+ sum("" Every producing imp "") # Variable Income
- sum("" Every manufacturing imp has an associated v cost "") # Variable Cost
) / 1) <-- Relevant part
m.solve(disp=True)
Iter: 1 I: 0 Tm: 0.00 NLPi: 4 Dpth: 0 Lvs: 3 Obj: -1.05E+06 Gap: NaN
--Integer Solution: -1.04E+06 Lowest Leaf: -1.05E+06 Gap: 9.67E-03
Iter: 2 I: 0 Tm: 0.00 NLPi: 2 Dpth: 1 Lvs: 2 Obj: -1.04E+06 Gap: 9.67E-03
Iter: 3 I: 0 Tm: 0.00 NLPi: 4 Dpth: 1 Lvs: 4 Obj: -1.06E+06 Gap: 9.67E-03
--Integer Solution: -1.05E+06 Lowest Leaf: -1.06E+06 Gap: 4.78E-03
Iter: 4 I: 0 Tm: 0.00 NLPi: 2 Dpth: 2 Lvs: 3 Obj: -1.05E+06 Gap: 4.78E-03
.
.
.
Objective : -1050396.901745295
Running the imps values given back into the formula will confirm that the imps given by this optimization indeed lead to an "income" of 1,050,396.90
Now changing the objective formula:
m.Maximize((
f.fixed_city_income(2500, 2500, commerce, pollution_index, 365, x[15], x[16]) # Fixed Income
- sum("" Base cost for every imp "") # Fixed Cost
+ sum("" Every producing imp "") # Variable Income
- sum("" Every manufacturing imp has an associated v cost "") # Variable Cost
) / 100) <-- Relevant part
Iter: 1 I: 0 Tm: 0.00 NLPi: 12 Dpth: 0 Lvs: 3 Obj: -1.06E+04 Gap: NaN
--Integer Solution: -1.06E+04 Lowest Leaf: -1.06E+04 Gap: 1.25E-03
Iter: 2 I: 0 Tm: 0.00 NLPi: 2 Dpth: 1 Lvs: 2 Obj: -1.06E+04 Gap: 1.25E-03
Iter: 3 I: 0 Tm: -0.00 NLPi: 1 Dpth: 1 Lvs: 4 Obj: -1.06E+04 Gap: 1.25E-03
Iter: 4 I: 0 Tm: 0.00 NLPi: 1 Dpth: 1 Lvs: 5 Obj: -1.06E+04 Gap: 1.25E-03
.
.
.
Objective : -10613.94773200687
New values through formula -> 1,061,394.77
Thus better solution