本文整理汇总了Python中gurobipy.Model.addVar方法的典型用法代码示例。如果您正苦于以下问题:Python Model.addVar方法的具体用法?Python Model.addVar怎么用?Python Model.addVar使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类gurobipy.Model
的用法示例。
在下文中一共展示了Model.addVar方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: create_problem
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def create_problem(cobra_model, objective_sense="maximize"):
lp = Model("cobra")
lp.Params.OutputFlag = 0
if objective_sense == "maximize":
objective_sign = -1.0
elif objective_sense == "minimize":
objective_sign = 1.0
else:
raise ValueError("objective_sense must be 'maximize' or 'minimize'")
# create metabolites/constraints
metabolite_constraints = {}
for metabolite in cobra_model.metabolites:
metabolite_constraints[metabolite] = lp.addConstr(
0.0, sense_dict[metabolite._constraint_sense], metabolite._bound, metabolite.id
)
lp.update()
# create reactions/variables along with S matrix
for j, reaction in enumerate(cobra_model.reactions):
constraints = [metabolite_constraints[i] for i in reaction._metabolites]
stoichiometry = reaction._metabolites.values()
lp.addVar(
lb=float(reaction.lower_bound),
ub=float(reaction.upper_bound),
obj=objective_sign * reaction.objective_coefficient,
name=reaction.id,
vtype=variable_kind_dict[reaction.variable_kind],
column=Column(stoichiometry, constraints),
)
lp.update()
return lp
示例2: solve_lp_knapsack_gurobi
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def solve_lp_knapsack_gurobi(scores, costs, budget):
from gurobipy import Model, LinExpr, GRB
n = len(scores)
# Create a new model.
m = Model("lp_knapsack")
# Create variables.
for i in range(n):
m.addVar(lb=0.0, ub=1.0)
m.update()
vars = m.getVars()
# Set objective.
obj = LinExpr()
for i in range(n):
obj += scores[i] * vars[i]
m.setObjective(obj, GRB.MAXIMIZE)
# Add constraint.
expr = LinExpr()
for i in range(n):
expr += costs[i] * vars[i]
m.addConstr(expr, GRB.LESS_EQUAL, budget)
# Optimize.
m.optimize()
assert m.status == GRB.OPTIMAL
x = np.zeros(n)
for i in range(n):
x[i] = vars[i].x
return x
示例3: build_model
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def build_model(plants, warehouses, capacity, demand, fixed_costs, trans_costs):
# decision variables
m = Model("facility")
is_open = []
for p in plants:
is_open.append(m.addVar(vtype=GRB.BINARY,
name="is_open[{}]".format(p)))
trans_qty = []
for w in warehouses:
trans_qty.append([])
for p in plants:
trans_qty[w].append(m.addVar(vtype=GRB.CONTINUOUS,
name="trans_qty[{}.{}]".format(p, w),
lb=0.0))
m.update()
# objective function
m.setObjective(quicksum(fixed_costs[p] * is_open[p]
for p in plants) +
quicksum(trans_costs[w][p] * trans_qty[w][p]
for w in warehouses
for p in plants),
GRB.MINIMIZE)
# constraints
for p in plants:
m.addConstr(quicksum(trans_qty[w][p] for w in warehouses) <= capacity[p] * is_open[p],
"Capacity({})".format(p))
for w in warehouses:
m.addConstr(quicksum(trans_qty[w][p] for p in plants) == demand[w],
"Demand({})".format(w))
m.update()
return m
示例4: generateInstance
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def generateInstance(self):
def euc_dist(bor, sh):
dx = bor["x_coord"] - sh["x_coord"]
dy = bor["y_coord"] - sh["y_coord"]
return math.sqrt(dx * dx + dy * dy)
model = Model('FireSolver')
# Generate variables
x = {}
for bor in self.boroughs:
# New firehouses
for fh in self.new_firehouses + self.old_firehouses:
name = "x_" + fh["loc_id"] + "_" + bor["loc_id"]
x[bor["loc_id"], fh["loc_id"]] = model.addVar(name=name, vtype ="b", obj=self.cost_coef * euc_dist(bor, fh))
# Open variables
openfh = {}
for fh in self.new_firehouses:
openfh[fh["loc_id"]] = model.addVar(name = "open_" + fh["loc_id"], vtype ="b", obj=fh["construction_cost"])
# Close variables
closefh = {}
for fh in self.old_firehouses:
closefh[fh["loc_id"]] = model.addVar(name = "close_" + fh["loc_id"], vtype ="b", obj=fh["destruction_cost"])
model.modelSense = GRB.MINIMIZE
model.update()
# Constraints: one firehouse / borough
for bor in self.boroughs:
model.addConstr(quicksum(x[key] for key in x if key[0] == bor["loc_id"]) == 1)
# capacity of firehouses
for fh in self.new_firehouses:
model.addConstr(quicksum(x[key] for key in x if key[1] == fh["loc_id"]) <= self.capacity * openfh[fh["loc_id"]])
# If it is not removed, the initial assignment needs to be respected
for fh in self.old_firehouses:
for bor in self.boroughs:
if bor["currently_protected_by"] == fh["loc_id"]:
model.addConstr(x[bor["loc_id"], fh["loc_id"]] == 1 - closefh[fh["loc_id"]])
else:
model.addConstr(x[bor["loc_id"], fh["loc_id"]] == 0)
# solve it
model.optimize()
self.model = model
示例5: ilp
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def ilp(costMatrix):
#Invalid_Connections : -1
if costMatrix.shape==(0,0):
return []
dist_mat=numpy.copy(costMatrix)
dist_mat[costMatrix==-1]=10e10
size_x = dist_mat.shape[0]
size_y = dist_mat.shape[1]
size_min = int(numpy.amin([size_x,size_y]))
from gurobipy import Model, quicksum, GRB
m=Model("mip1")
COS,VAR={},{}
for i in range(size_x):
x_cos, x_var = [],[]
for j in range(size_y):
COS[i,j]=dist_mat[i,j]
VAR[i,j]=m.addVar(vtype='B',name="["+str(i)+","+str(j)+"]")
m.update()
# Set objective
m.setObjective( quicksum(\
COS[x,y]*VAR[x,y]
for x in range(size_x) \
for y in range(size_y) \
),GRB.MINIMIZE)
# Constrains HORIZONTAL
for i in range(size_x):
m.addConstr( quicksum\
(VAR[i,y] for y in range(size_y)) <= 1)
# Constrains VERTICAL
for i in range(size_y):
m.addConstr( quicksum\
(VAR[x,i] for x in range(size_x)) <= 1)
m.addConstr(quicksum(\
VAR[x,y] for x in range(size_x) for y in range(size_y)) == int(size_min))
m.setParam("OutputFlag",False)
m.optimize()
res=numpy.zeros(dist_mat.shape,dtype=bool)
for i in range(size_x):
for j in range(size_y):
res[i,j]=VAR[i,j].x
binMatrix = numpy.zeros( costMatrix.shape,dtype=bool )
binMatrix[res==1]=1
binMatrix[costMatrix==-1]=0
return binMatrix
示例6: build_gurobi_model
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def build_gurobi_model(case):
G, B = case.G, case.B
P = real(case.demands)
Q = imag(case.demands)
branches = case.branch_list
n = len(case.demands)
vhat = case.vhat
s2 = 2**.5
gens = {bus: gen.v for bus, gen in case.gens.items()}
del gens[0]
m = GurobiModel("jabr")
u = [m.addVar(name='u_%d'%i) for i in range(n)]
R = {(i, j): m.addVar(name='R_%d_%d' % (i, j)) for i, j in branches}
I = {(i, j): m.addVar(lb=-GRB.INFINITY, name='I_%d_%d' % (i, j)) for i, j in branches}
for i, j in branches:
R[j, i] = R[i, j]
I[j, i] = I[i, j]
m.update()
m.addConstr(u[0] == vhat*vhat/s2, 'u0')
for gen, v in gens.iteritems():
m.addConstr(u[gen] == v*v/s2, 'u%d' % gen)
for i, j in branches:
m.addQConstr(2*u[i]*u[j] >= R[i,j]*R[i,j] + I[i,j]*I[i,j], 'cone_%d_%d' % (i, j))
k = lambda i: (j for j in B[i, :].nonzero()[1])
s = lambda i, j: 1 if i < j else -1
for i in range(1, n):
m.addConstr(-s2*u[i]*G[i, :].sum() + quicksum(G[i,j]*R[i,j] + B[i,j]*s(i,j)*I[i,j] for j in k(i)) == P[i],
'real_flow_%d_%d' % (i, j))
if i in gens:
continue
m.addConstr(s2*u[i]*B[i, :].sum() + quicksum(-B[i,j]*R[i,j] + G[i,j]*s(i,j)*I[i,j] for j in k(i)) == Q[i],
'reac_flow_%d_%d' % (i, j))
m.setObjective(quicksum(R[i,j] for i, j in branches), sense=GRB.MAXIMIZE)
m.params.outputFlag = 0
#m.params.barQCPConvTol = 5e-10
m.optimize()
if m.status != 2:
raise ValueError("gurobi failed to converge: %s (check log)" % m.status)
u_opt = [x.getAttr('x') for x in u]
R_opt = {(i, j): x.getAttr('x') for (i, j), x in R.items()}
I_opt = {(i, j): x.getAttr('x') for (i, j), x in I.items()}
return u_opt, R_opt, I_opt
示例7: create_problem
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def create_problem(cobra_model, quadratic_component=None, **kwargs):
"""Solver-specific method for constructing a solver problem from
a cobra.Model. This can be tuned for performance using kwargs
"""
lp = Model("")
the_parameters = parameter_defaults
if kwargs:
the_parameters = parameter_defaults.copy()
the_parameters.update(kwargs)
# Set verbosity first to quiet infos on parameter changes
if "verbose" in the_parameters:
set_parameter(lp, "verbose", the_parameters["verbose"])
for k, v in iteritems(the_parameters):
set_parameter(lp, k, v)
# Create variables
#TODO: Speed this up
variable_list = [lp.addVar(_float(x.lower_bound),
_float(x.upper_bound),
float(x.objective_coefficient),
variable_kind_dict[x.variable_kind],
str(i))
for i, x in enumerate(cobra_model.reactions)]
reaction_to_variable = dict(zip(cobra_model.reactions,
variable_list))
# Integrate new variables
lp.update()
#Constraints are based on mass balance
#Construct the lin expression lists and then add
#TODO: Speed this up as it takes about .18 seconds
#HERE
for i, the_metabolite in enumerate(cobra_model.metabolites):
constraint_coefficients = []
constraint_variables = []
for the_reaction in the_metabolite._reaction:
constraint_coefficients.append(_float(the_reaction._metabolites[the_metabolite]))
constraint_variables.append(reaction_to_variable[the_reaction])
#Add the metabolite to the problem
lp.addConstr(LinExpr(constraint_coefficients, constraint_variables),
sense_dict[the_metabolite._constraint_sense.upper()],
the_metabolite._bound,
str(i))
# Set objective to quadratic program
if quadratic_component is not None:
set_quadratic_objective(lp, quadratic_component)
lp.update()
return(lp)
示例8: global_model
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def global_model(N, k_choices, distance_matrix):
if k_choices >= N:
raise ValueError("k_choices must be less than N")
model = Model("distance1")
trajectories = range(N)
distance_matrix = np.array(
distance_matrix / distance_matrix.max(), dtype=np.float64)
dm = distance_matrix ** 2
y, x = {}, {}
for i in trajectories:
y[i] = model.addVar(vtype="B", obj=0, name="y[%s]" % i)
for j in range(i + 1, N):
x[i, j] = model.addVar(
vtype="B", obj=1.0, name="x[%s,%s]" % (i, j))
model.update()
model.setObjective(quicksum([x[i, j] * dm[j][i]
for i in trajectories
for j in range(i + 1, N)]))
# Add constraints to the model
model.addConstr(quicksum([y[i]
for i in trajectories]) <= k_choices, "27")
for i in trajectories:
for j in range(i + 1, N):
model.addConstr(x[i, j] <= y[i], "28-%s-%s" % (i, j))
model.addConstr(x[i, j] <= y[j], "29-%s-%s" % (i, j))
model.addConstr(y[i] + y[j] <= 1 + x[i, j],
"30-%s-%s" % (i, j))
model.addConstr(quicksum([x[i, j] for i in trajectories
for j in range(i + 1, N)])
<= nchoosek(k_choices, 2), "Cut_1")
model.update()
return model
示例9: find_feasible_start
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def find_feasible_start(n_colors, h, statespace, conflicts, verbose=False):
model = Model("TimeFeasibility")
p = len(h)
y = {}
# y[i,k] = if color i gets slot l
for i in range(n_colors):
for l in range(p):
y[i,l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l))
model.update()
# Building constraints...
# c1: all get one
for i in range(n_colors):
model.addConstr( quicksum([ y[i, l] for l in range(p) ]) == 1, "c1")
# c2: each slot needs to be used tops once
for l in range(p):
model.addConstr( quicksum([ y[i, l] for i in range(n_colors) ]) <= 1, "c2")
### c3: statespace constraints
for i in range(n_colors):
#print l, h[l], i, [s for s in statespace]
model.addConstr( quicksum([ y[i, l] for l in range(p) if h[l] not in statespace[i] ]) == 0, "c3")
# objective: minimize conflicts
#obj = quicksum([ y[i,l] * y[j,l] for l in range(p) for i in range(n_colors) for j in range(i+1, n_colors) ])
obj = quicksum([ sum(y[i,l] for i in range(n_colors)) for l in range(p) ])
#obj = 0
model.setObjective(obj, GRB.MINIMIZE)
if not verbose:
model.params.OutputFlag = 0
model.optimize()
# return best room schedule
color_schedule = []
if model.status == GRB.INFEASIBLE:
return color_schedule
for i in range(n_colors):
for l in range(p):
v = model.getVarByName("y_%s_%s" % (i,l))
if v.x == 1:
color_schedule.append(h[l])
break
return color_schedule
示例10: check_feasability_ILP
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def check_feasability_ILP(exams_to_schedule, period, data, verbose=False):
# More precise but by far to slow compared to heuristic
r = data['r']
T = data['T']
s = data['s']
z = {}
model = Model("RoomFeasability")
# z[i,k] = if exam i is written in room k
for k in range(r):
# print k, period
if T[k][period] == 1:
for i in exams_to_schedule:
z[i, k] = model.addVar(vtype=GRB.BINARY, name="z_%s_%s" % (i, k))
model.update()
# Building constraints...
# c1: seats for all students
for i in exams_to_schedule:
expr = LinExpr()
for k in range(r):
if T[k][period] == 1:
expr.addTerms(1, z[i, k])
model.addConstr(expr >= s[i], "c1")
# c2: only one exam per room
for k in range(r):
if T[k][period] == 1:
expr = LinExpr()
for i in exams_to_schedule:
expr.addTerms(1, z[i, k])
model.addConstr(expr <= 1, "c2")
model.setObjective(0, GRB.MINIMIZE)
if not verbose:
model.params.OutputFlag = 0
model.params.heuristics = 0
model.params.PrePasses = 1
model.optimize()
# return best room schedule
try:
return model.objval
except GurobiError:
logging.warning('check_feasability_ILP: model has no objVal')
return None
示例11: solve
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def solve(budget, buses, lines, u, c, b, S, D):
m = Model('inhibit')
w, v, y = {}, {}, {}
for i in buses:
w[i] = m.addVar(vtype=GRB.BINARY, name="w_%s" % i)
for i, j in lines:
v[i, j] = m.addVar(vtype=GRB.BINARY, name='v_%s_%s' % (i, j))
y[i, j] = m.addVar(vtype=GRB.BINARY, name='y_%s_%s' % (i, j))
m.update()
for i, j in lines:
m.addConstr(w[i]-w[j] <= v[i, j] + y[i, j], 'balance1_%s_%s' % (i, j))
m.addConstr(w[j]-w[i] <= v[i, j] + y[i, j], 'balance2_%s_%s' % (i, j))
m.addConstr(quicksum(c[i, j]*y[i, j] for i, j in lines) <= budget, 'budget')
m.setObjective(quicksum(u[i, j]*v[i, j] for i, j in lines) +
quicksum(b[i]*(1-w[i]) for i in S) -
quicksum(b[i]*w[i] for i in D))
m.setParam('OutputFlag', 0)
m.optimize()
m.write('gurobi.lp')
return w, v, y, m
示例12: _cut
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def _cut(self, model, val_func, cut_func):
'''Returns true if a cut was added to the master'''
problem = self.problem
theta = self.theta
x = self.x
# Create subproblem.
sub = Model()
# y[ip,iq,s,c] = 1 if images ip & iq have a shared path through stage
# s by running command c during s, 0 otherwise
y = {}
for (ip, iq), cmds in problem.shared_cmds.items():
for s, c in product(problem.shared_stages[ip, iq], cmds):
y[ip,iq,s,c] = sub.addVar(name='y[%s,%s,%s,%s]' % (ip,iq,s,c))
sub.update()
# Find shared paths among image pairs.
constraints = defaultdict(list)
for (ip, iq), cmds in problem.shared_cmds.items():
for s in problem.shared_stages[ip,iq]:
for c in cmds:
constraints[ip,s,c].append(sub.addConstr(y[ip,iq,s,c] <= val_func(model, x[ip,s,c])))
constraints[iq,s,c].append(sub.addConstr(y[ip,iq,s,c] <= val_func(model, x[iq,s,c])))
if s > 1:
sub.addConstr(sum(y[ip,iq,s,c] for c in cmds) <= sum(y[ip,iq,s-1,c] for c in cmds))
sub.setObjective(
-sum(problem.commands[c] * y[ip,iq,s,c] for ip,iq,s,c in y),
GRB.MINIMIZE
)
sub.optimize()
# Add the dual prices for each variable
pi = defaultdict(float)
for isp, cons in constraints.iteritems():
for c in cons:
pi[isp] += c.pi
# Detect optimality
if val_func(model, theta) >= sub.objVal:
return False # no cuts to add
# Optimality cut
cut_func(model, theta >= sum(pi[isp]*x[isp] for isp in pi if pi[isp]))
return True
示例13: two_cycle
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def two_cycle(A, C, gap):
"""
Solve high-vertex dense graphs by reduction to
weighted matching ILP.
"""
_ = '*'
m = Model()
m.modelsense = GRB.MAXIMIZE
m.params.mipgap = gap
m.params.timelimit = 60 * 60
n = A.shape[0]
vars = {}
edges = tuplelist()
# model as undirected graph
for i in range(n):
for j in range(i+1, n):
if A[i, j] == 1 and A[j, i] == 1:
e = (i, j)
edges.append(e)
w_i = 2 if i in C else 1
w_j = 2 if j in C else 1
w = w_i + w_j
var = m.addVar(vtype=GRB.BINARY, obj=w)
vars[e] = var
m.update()
# 2 cycle constraint <=> undirected flow <= 1
for i in range(n):
lhs = LinExpr()
lhs_vars = [vars[e] for e in chain(edges.select(i, _), edges.select(_, i))]
ones = [1.0]*len(lhs_vars)
lhs.addTerms(ones, lhs_vars)
m.addConstr(lhs <= 1)
m.optimize()
m.update()
cycles = [list(e) for e in edges if vars[e].x == 1.0]
return cycles, m.objval
示例14: build_model
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def build_model(data, n_cliques = 0, verbose = True):
# Load Data Format
n = data['n']
r = data['r']
p = data['p']
s = data['s']
c = data['c']
h = data['h']
w = data['w']
location = data['location']
conflicts = data['conflicts']
locking_times = data['locking_times']
T = data['T']
similarp = data['similarp']
model = Model("ExaminationScheduling")
if verbose:
print("Building variables...")
# x[i,k,l] = 1 if exam i is at time l in room k
x = {}
for k in range(r):
for l in range(p):
if T[k][l] == 1:
for i in range(n):
if location[k] in w[i]:
x[i,k,l] = model.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (i,k,l))
# y[i,l] = 1 if exam i is at time l
y = {}
for i in range(n):
for l in range(p):
y[i, l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l))
# integrate new variables
model.update()
# for i in range(p+5):
# for l in range(i-5):
# y[i, l].setAttr("BranchPriority", s[i])
# model.update()
start = timeit.default_timer()
# not very readable but same constraints as in GurbiLinear_v_10: speeded up model building by 2 for small problems (~400 exams) and more for huger problem ~1500 exams
if verbose:
print("Building constraints...")
s_sorted = sorted(range(len(c)), key = lambda k: c[k])
obj = LinExpr()
sumconflicts = {}
maxrooms = {}
for i in range(n):
sumconflicts[i] = sum(conflicts[i])
if s[i] <= 50:
maxrooms[i] = 1
elif s[i] <= 100:
maxrooms[i] = 2
elif s[i] <= 400:
maxrooms[i] = 7
elif s[i] <= 700:
maxrooms[i] = 9
else:
maxrooms[i] = 12
c2 = LinExpr()
c4 = LinExpr()
for l in range(p):
c1 = LinExpr()
c1 = LinExpr()
c3 = LinExpr()
for k in range(r):
if T[k][l] == 1 and location[k] in w[i]:
# print k, c[k], 1-(1/(pow(2,s_sorted.index(k))))
obj.addTerms( 1-(1/(pow(2,s_sorted.index(k)))) , x[i, k, l])
c1.addTerms(1, x[i,k,l])
c4.addTerms(c[k],x[i,k,l])
model.addConstr(c1 <= maxrooms[i]* y[i,l], "c1a")
model.addConstr(c1 >= y[i,l], "C1b")
for j in conflicts[i]:
c3.addTerms(1,y[j,l])
model.addConstr(c3 <= (1 - y[i,l])*sumconflicts[i], "c3")
c2.addTerms(1,y[i,l])
model.addConstr( c2 == 1 , "c2")
model.addConstr(c4 >= s[i], "c4")
sumrooms = {}
for l in range(p):
sumrooms[l] = 0
cover_inequalities = LinExpr()
for k in range(r):
if T[k][l] == 1:
sumrooms[l] += 1
#.........这里部分代码省略.........
示例15: gurobi
# 需要导入模块: from gurobipy import Model [as 别名]
# 或者: from gurobipy.Model import addVar [as 别名]
def gurobi(wanted_parts, available_parts, stores, shipping_cost=10.0):
from gurobipy import Model, GRB, LinExpr
kf1 = lambda x: (x['item_id'], x['wanted_color_id'])
kf2 = lambda x: (x['ItemID'], x['ColorID'])
available_by_store = utils.groupby(available_parts, lambda x: x['store_id'])
store_by_id = dict( (s['store_id'], s) for s in stores )
m = Model()
store_variables = {} # store id to variable indicating store is used
quantity_variables = [] # list of all lot variables + metadata
# for every store
for (store_id, inventory) in available_by_store.iteritems():
# a variable for if anything was bought from this store. if 1, then pay
# shipping cost and all store inventory is available; if 0, then don't pay
# for shipping and every lot in it has 0 quantity available
store_variables[store_id] = m.addVar(0.0, 1.0, shipping_cost, GRB.BINARY,
"use-store=%s" % (store_id,))
for lot in inventory:
store_id = lot['store_id']
quantity = lot['quantity_available']
unit_cost= lot['cost_per_unit']
item_id = lot['item_id']
color_id = lot['color_id']
# a variable for how much to buy of this lot
v = m.addVar(0.0, quantity, unit_cost, GRB.CONTINUOUS,
"quantity-store=%s-item=%s-color=%s" % (store_id, item_id, color_id))
# keep a list of all lots
quantity_variables.append({
'store_id': store_id,
'item_id': lot['item_id'],
'wanted_color_id': lot['wanted_color_id'],
'color_id': lot['color_id'],
'variable': v,
'quantity_available': quantity,
'cost_per_unit': unit_cost
})
# actually put the variables into the model
m.update()
# for every lot in every store
for lot in quantity_variables:
use_store = store_variables[lot['store_id']]
quantity = lot['quantity_available']
unit_cost = lot['cost_per_unit']
v = lot['variable']
# a constraint for how much can be bought
m.addConstr(LinExpr([1.0, -1 * quantity], [v, use_store]),
GRB.LESS_EQUAL, 0.0,
"maxquantity-store=%s-item=%s-color-%d" % (lot['store_id'], lot['item_id'], lot['color_id']))
# for every wanted lot
variables_by_id = utils.groupby(quantity_variables, kf1)
for lot in wanted_parts:
# a constraint saying amount bought >= wanted amount
variables = map(lambda x: x['variable'], variables_by_id[kf2(lot)])
constants = len(variables) * [1.0]
m.addConstr(LinExpr(constants, variables),
GRB.GREATER_EQUAL, lot['Qty'],
"wantedamount-item=%s-color=%s" % (lot['ItemID'], lot['ColorID']))
# for every store
variables_by_store = utils.groupby(quantity_variables, lambda x: x['store_id'])
for (store_id, variables) in variables_by_store.iteritems():
use_store = store_variables[store_id]
minimum_purchase = store_by_id[store_id]['minimum_buy']
# a constraint saying "if I purchased from this store, I bought the minimum amount or more"
constants = [v['cost_per_unit'] for v in variables] + [-1 * minimum_purchase]
variables = [v['variable'] for v in variables] + [use_store]
m.addConstr(LinExpr(constants, variables),
GRB.GREATER_EQUAL, 0.0,
"minbuy-store=%d" % (store_id,))
# minimize sum of costs of items bought + shipping costs
m.setParam(GRB.param.MIPGap, 0.01) # stop when duality gap <= 1%
m.optimize()
# get results
if m.ObjVal < float('inf'):
result = []
for lot in quantity_variables:
# get variable out
v = lot['variable']
del lot['variable']
# lot variables are continuous, so they might not actually be integral.
# If they're not, check that they're "almost" integral, so we can just
# round. Otherwise, print this warning. According to theory the optimal
# solution is for all continuous variables to be integral.
if v.X != int(v.X) and abs(v.X - round(v.X)) > 1e-3:
#.........这里部分代码省略.........