Search code examples
integerconstraintslinear-programmingpyomo

LP - PYOMO , constraint with integer variable


Another problem that arose for my project. I have an integer variable for whether a plant will be used for manufacturing. The issues are: When writing the constraint for the capacity of the plant i get an error. Same thing happens for the variable that controls that the objective function does not turn to 0 from minimising the integer variable:

The demand for each order
demand= {782912: 808, 782913: 3188, 782914: 2331, 782915: 847, 782916: 2163,789954:5643}

#The cost per unit produced for each order based in which factory chosen
total cost= { (782912, 'PLANT16'): 0.46, (782913, 'PLANT16'): 0.46, (782914, 'PLANT16'): 0.46, (782915, 'PLANT16'): 0.46, (782916, 'PLANT16'): 0.46}, (789954,'PLANT05'):0.90,(789954,'PLANT07'):0.91,(789954,'PLANT08'):1.13,(789954,'PLANT10'):0.12}

    #The capacity of each factory. 
#!!!!!!!in terms of the number of orders it can satisfy-no the quantity of the orders !!!!!
    supply= {'PLANT05': 531,'PLANT07': 841,'PLANT08': 1107,'PLANT10': 981,'PLANT16': 2313}

The part bellow functions as should

#Concrete model
model=pyo.ConcreteModel()
#Sets
model.i=pyo.Set(initialize=demand.keys()) #orders
model.j=pyo.Set(initialize=supply.keys()) #factories
model.select_combos = pyo.Set(within = model.i * model.j, initialize = total_costs_per_unit.keys())

#Parameters
model.p=pyo.Param(model.select_combos, initialize=total_costs_per_unit) # here goes the cost dictionary

model.d=pyo.Param(model.i,initialize=demand)

model.s=pyo.Param(model.j,initialize=supply)

#Decision variable
model.x=pyo.Var(model.select_combos, within=pyo.NonNegativeReals)
model.Assign=pyo.Var(model.select_combos, domain=pyo.Binary)  # assign order to factoy
#Objective function

#plant_used = pyo.summation(model.plants_binary, m.Assign)
model.Obj=pyo.Objective(expr=sum(model.p[i,j]*model.x[i,j]*model.Assign[i,j] for i,j in model.select_combos),sense=pyo.minimize)

#Constraints
def Const1(model,i):
  return sum(model.x[i,j] for j in model.j if (i,j) in model.select_combos)>=model.d[i]
model.condemand=pyo.Constraint(model.i,rule=Const1)

My first attempt at creating a constraint so that the total n of orders (i) satisfied from each factory (j), does not exceed the capacity of the plant (model.s[j])

'''the number of orders when x>0 from each factory <= of capacity'''
def Const5(model,j):  #does not work
  return np.count_nonzero(model.x[i,j] for i in model.i if (i,j) in model.select_combos)<=model.s[j]
model.consupply=pyo.Constraint(model.j,rule=Const5)

The issue is that it returns True or False which can not be an input in constraint

My second attempt:

def Const6(model,j):
    return sum(model.Assign[i, j] for i in model.i if (i,j) in model.select_combos) <= model.s[j]
model.consupply=pyo.Constraint(model.j,rule=Const6)

CplexSolverError: CPLEX Error  1016: Community Edition. Problem size limits exceeded.

And the other constraint:

'''we want a constraint for model.Assign[i, j], so that our obsective fanction does not turn to 0'''
def Const7(model,i):
    return (100000*model.Assign[i, j] for j in model.j if (i,j) in model.select_combos)>=model.x[i,j]
model.consplant_binary=pyo.Constraint(model.i,rule=Const7)

NameError: name 'j' is not defined

Please let me know if you have any idea what I am doing wrong cause I am lost. Cannot find anything in my online course about that situation.

Thank you in advance.


Solution

  • CPLEX Error 1016: Community Edition. Problem size limits exceeded.

    means that your model is too big for CPLEX free community edition.

    So what you could do:

    • Use an academic free CPLEX version if you are in academia
    • Buy CPLEX full version
    • Rely on CPLEX as a service in the IBM Cloud