defcreate_rmp(self, size, amount, width): """Create the restricted master problem""" rmp = Model("rmp") var = rmp.continuous_var_list(range(len(size)), name="x")
rmp.minimize(rmp.sum(var))
for i inrange(len(self.size)): self.pattens[i][i] = width // size[i] ctns = rmp.add_constraints([(width // size[i]) * var[i] >= amount[i] for i inrange(len(size))])
return rmp, var, ctns
defcreate_pricing_problem(self, size, prices, width): """Create the prices problem mdl with prices, and return mdl""" mdl = Model("pricing") mdl.a = mdl.integer_var_list( range(len(size)), ub=[width // size[i] for i inrange(len(size))], name="a") mdl.minimize(1 - mdl.dot(mdl.a, prices)) mdl.add_constraint(mdl.dot(mdl.a, size) <= width)
return mdl
defupdate_pricing_problem(self, prices): """Update the prices problem mdl with prices""" expr = self.pricing_prob.objective_expr updated = [(var, -prices[u]) for u, var inenumerate(self.pricing_prob.a)] expr.set_coefficients(updated)
defprint_sol(self, sol): """Print the cut details in solution sol""" print("Current need %d" % sol.objective_value) for i, p inenumerate(self.pattens): if sol[self.vars[i]] > 0: print("\t", p, sol[self.vars[i]])
defsolve(self): """Solve the prolbem""" iter = 0 whileTrue: iter += 1 self.rmp.export_as_lp("rmp_%d.lp" % iter)
self.pricing_prob.export_as_lp("pricing_%d.lp" % iter) sol = self.pricing_prob.solve()
new_pattern = None if sol: if sol.objective_value < 0: print("The retuced cost is %6.3f" % sol.objective_value) new_pattern = [ sol[self.pricing_prob.a[i]] for i inrange(len(self.size)) ]
if new_pattern: print("New patten found", new_pattern) self.pattens.append(new_pattern) # Add one new variables, i.e., a new patten new_var = self.rmp.continuous_var(name="x_%d" % len(self.vars)) self.vars.append(new_var) # Update constraints for n, ct inenumerate(self.ctns): ct.lhs += new_pattern[n] * self.vars[-1] # Update objective function obj_expr = self.rmp.get_objective_expr() obj_expr += self.vars[-1] else: # No new patten, the best scheme found print("The best cut method is:") self.print_sol(sol_rmp) break