Import Solution#
This is helpful if limitations prevent you from generating the solution internally.
This could be necessitated by things such as:
incompatibility in python version required for gana and solver
loading saved results to then update the model
An example pipeline would be:
Use gana to generate .mps file in environment 1
Generate a gurobi model in environment 2 from .mps using .read()
Solve, and save solution as .pkl or .mps
Load solution into gana model in environment 1 using import_solution
Take the diet problem for example#
In Environment 1#
# !pip install gana # uncomment and run to install Gana, if not in environment
from gana import Prg, I, V, P, inf
p = Prg()
p.item = I('milk', 'cheese', 'apples', tag='food item')
p.x = V(p.item, tag='amount of food item to intake')
p.protein = P(p.item, _=[40, 20, 10])
p.vitA = P(p.item, _=[5, 40, 30])
p.vitB = P(p.item, _=[20, 30, 40])
p.vitC = P(p.item, _=[30, 50, 60])
p.cost = P(p.item, _=[1, 2.5, 3 / 4])
p.cons_protein = sum(p.protein(i) * p.x(i) for i in p.item) >= 80
p.cons_vitA = sum(p.vitA(i) * p.x(i) for i in p.item) >= 60
p.cons_vitB = sum(p.vitB(i) * p.x(i) for i in p.item) >= 50
p.cons_vitC = sum(p.vitC(i) * p.x(i) for i in p.item) >= 30
p.obj_cost = inf(sum(p.cost(i) * p.x(i) for i in p.item))
Now that the problem is formulated, generate a .mps file
p.mps()
📝 Generated prog.mps ⏱ 0.0039 s
In Environment 2#
Read the .mps file in another environment. Optimize the generated model
import gurobipy as gp
gm = gp.read('prog.mps')
gm.optimize()
Read MPS format model from file prog.mps
Reading time = 0.00 seconds
PROG: 4 rows, 3 columns, 12 nonzeros
Gurobi Optimizer version 12.0.3 build v12.0.3rc0 (mac64[x86] - Darwin 21.6.0 21H1320)
CPU model: Intel(R) Core(TM) i7-6567U CPU @ 3.30GHz
Thread count: 2 physical cores, 4 logical processors, using up to 4 threads
Optimize a model with 4 rows, 3 columns and 12 nonzeros
Model fingerprint: 0x7c6539af
Coefficient statistics:
Matrix range [5e+00, 6e+01]
Objective range [8e-01, 2e+00]
Bounds range [0e+00, 0e+00]
RHS range [3e+01, 8e+01]
Presolve time: 0.03s
Presolved: 4 rows, 3 columns, 12 nonzeros
Iteration Objective Primal Inf. Dual Inf. Time
0 0.0000000e+00 2.750000e+01 0.000000e+00 0s
2 2.8695652e+00 0.000000e+00 0.000000e+00 0s
Solved in 2 iterations and 0.04 seconds (0.00 work units)
Optimal objective 2.869565217e+00
Save solution as JSON or pickle file The objective needs to be passed as a float as well
import pickle
with open("sol.pkl", "wb") as f:
pickle.dump(([v.X for v in gm.getVars()], gm.ObjVal), f)
import json
with open("sol.json", "w") as f:
json.dump(([v.X for v in gm.getVars()], gm.ObjVal), f)
Back in Environment 1#
If using json
p.import_solution("sol.json")
📝 Generated Solution object for prog. See .solution ⏱ 0.0001 s
If using pickle
p.import_solution("sol.pkl")
📝 Generated Solution object for prog. See .solution ⏱ 0.0000 s
If both are loaded, it will just update them chronologically.
Recall that p.solution shows you the last updated solution
p.solutions
{0: Solution(name='prog_solution_0'), 1: Solution(name='prog_solution_1')}