Having a simplified problem: I'd like to assign an instance ID anywhere in in the instance_map
. The goal is to have the ID's uniquely distributed over the instance_map, so each ID should occur exatcly once.
Pyomo in turn raises that this task is unfeasbile and most surprisingly started assigning with floats in an integer domain. Here's the code
import pyomo.environ as pe
model = pe.ConcreteModel()
model.rows = pe.RangeSet(1, 2)
model.cols = pe.RangeSet(1, 5)
model.instances = pe.RangeSet(1, 5)
model.n_instances = pe.Var(initialize=5)
model.n_cols = pe.Var(initialize=5)
model.n_rows = pe.Var(initialize=2)
model.instances_map = pe.Var(model.rows, model.cols, within=pe.Integers, initialize=0, bounds=(0, model.n_instances.value))
def unique_instances_check(model, instance):
if instance == 0:
return sum(model.instances_map[i,j] == instance for i in model.rows for j in model.cols) >= 0
else:
return sum(model.instances_map[i,j] == instance for i in model.rows for j in model.cols) == 1
model.C1 = pe.Constraint(model.instances, rule=unique_instances_check)
def objective(model):
return sum(model.instances_map[1,j] for j in model.cols)
model.obj = pe.Objective(rule=objective, sense=pe.minimize)
opt = pe.SolverFactory("ipopt").solve(model)
model.instances_map.pprint()
When running it I get the the following output for the last code line
WARNING: Loading a SolverResults object with a warning status into
model.name="unknown";
- termination condition: infeasible
- message from solver: Ipopt 3.14.5\x3a Converged to a locally
infeasible point. Problem may be infeasible.
instances_map : Size=10, Index=instances_map_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
(1, 1) : 0 : 5.000000049983252 : 5 : False : False : Integers
(1, 2) : 0 : 5.000000049983252 : 5 : False : False : Integers
(1, 3) : 0 : 5.000000049983252 : 5 : False : False : Integers
(1, 4) : 0 : 5.000000049983252 : 5 : False : False : Integers
(1, 5) : 0 : 5.000000049983252 : 5 : False : False : Integers
(2, 1) : 0 : 5.000000049983252 : 5 : False : False : Integers
(2, 2) : 0 : 5.000000049983252 : 5 : False : False : Integers
(2, 3) : 0 : 5.000000049983252 : 5 : False : False : Integers
(2, 4) : 0 : 5.000000049983252 : 5 : False : False : Integers
(2, 5) : 0 : 5.000000049983252 : 5 : False : False : Integers
I was expecting many 0 assignments but 1,2,3,4,5 only once.
I'm honestly not sure where to go from here
First, your problem is not converging to a feasible point, so there is no guarantee that the returned solution respects any constraints or bounds.
More importantly, ipopt
is a continuous interior point solver and ignores discrete domains. If you look at the solver output (by adding tee=True'
to the solve
call), you should see:
==> Warning: Treating __ binary and __ integer variables as continous.
at the top of the solver output log.