Hi,
I am trying to solve a model (python) where the coefficients in the linear objective function depend on the sum of certain solution variables.
All variables are binary.
I get the error 'Divisor must be a constant'.
Is there a way around this?
Thanks. Code:
from gurobipy import *
import math
import numpy
import openpyxl
# physicians
physicians = ['DrA', 'DrB']
# halfdays in planspan
planspan = ['MoAM', 'MoPM', 'TuAM', 'TuPM', 'WeAM', 'WePM', 'ThAM', 'ThPM', 'FrAM', 'FrPM']
# activities
activities = ['Admin1', 'Frac2', 'Spec3', 'Fleb4', 'Latr5', 'Endo6', 'Surg7', 'Surg8',
'Noth9', 'Annl10']
# Model
m = Model("motest1")
# Assignment variables: x[j,a,t] ==1 if physician j is assigned to activity a
# on half day t.
# Just as in workforce1.py, since an assignment model always produces integer solutions, we use
# continuous variables and solve as an LP.
x = []
n = 1
for j in physicians:
for t in planspan:
for a in activities:
x.append(m.addVar(vtype=GRB.BINARY, name="x%d%s_%s_%s" % (n,j,t,a)))
n = n+1
m.update()
# Add constraints to ensure that EXACTLY one of the activities is assigned
# note that sum(x[0:9]) does not include the 9th item labeled x10
m.addConstr(sum(x[0:10]) == 1)
m.addConstr(sum(x[10:20]) == 1)
m.addConstr(sum(x[20:30]) == 1)
m.addConstr(sum(x[30:40]) == 1)
m.addConstr(sum(x[40:50]) == 1)
m.addConstr(sum(x[50:60]) == 1)
m.addConstr(sum(x[60:70]) == 1)
m.addConstr(sum(x[70:80]) == 1)
m.addConstr(sum(x[80:90]) == 1)
m.addConstr(sum(x[90:100]) == 1)
# j=2
m.addConstr(sum(x[101:110]) == 1)
m.addConstr(sum(x[110:120]) == 1)
m.addConstr(sum(x[120:130]) == 1)
m.addConstr(sum(x[130:140]) == 1)
m.addConstr(sum(x[140:150]) == 1)
m.addConstr(sum(x[150:160]) == 1)
m.addConstr(sum(x[160:170]) == 1)
m.addConstr(sum(x[170:180]) == 1)
m.addConstr(sum(x[180:190]) == 1)
m.addConstr(sum(x[190:200]) == 1)
M = array([[ 2. , 2. ],
[ 0.83333333, 1.16666667],
[ 2.16666667, 2. ],
[ 0. , 0. ],
[ 0.5 , 0.16666667],
[ 0.5 , 0.83333333],
[ 1.5 , 1.16666667],
[ 0.83333333, 1.33333333],
[ 1.66666667, 1.33333333],
[ 0.2 , 0.2 ]])
C = array([[ 0.69230769, 0.69230769],
[ 0.72137137, 0.63005549],
[-0.67160603, 0.60671454],
[ 0. , 0. ],
[ 0.06355356, -0.31430663],
[ 0.76585138, 1.32377788],
[-0.43737702, -0.64233165],
[ 1.79534889, 0.61685841],
[ 0. , 0. ],
[ 0. , 0. ]])
obj = LinExpr()
for j in range(len(physicians)):
for a in range(len(activities)-2): # activity 2-8 (index starts at 0)
if j == 0:
rng = x[a:100:10] # this sum is the number of instances of each activity
elif j == 1:
rng = x[a+100:200:10]
d = sum(rng)
if d >= 0:
for i in range(len(rng)):
obj += 1/d * (d - M[a][j] + C[a][j]) * rng[i]
elif d == 0:
for i in range(len(rng)):
obj += (d - M[a][j] + C[a][j]) * rng[i]