def diet(F,N,a,b,c,d): """diet -- model for the modern diet problem Parameters: F - set of foods N - set of nutrients a[i] - minimum intake of nutrient i b[i] - maximum intake of nutrient i c[j] - cost of food j d[j][i] - amount of nutrient i in food j Returns a model, ready to be solved. """ model = Model("modern diet") # Create variables x,y,z = {},{},{} for j in F: x[j] = model.addVar(vtype="I", name="x(%s)" % j) for i in N: z[i] = model.addVar(lb=a[i], ub=b[i], vtype="C", name="z(%s)" % i) # Constraints: for i in N: model.addCons(quicksum(d[j][i]*x[j] for j in F) == z[i], name="Nutr(%s)" % i) model.setObjective(quicksum(c[j]*x[j] for j in F), "minimize") model.data = x,y,z return model
def test_model(): # create solver instance s = Model() # add some variables x = s.addVar("x", vtype = 'C', obj = 1.0) y = s.addVar("y", vtype = 'C', obj = 2.0) assert x.getObj() == 1.0 assert y.getObj() == 2.0 s.setObjective(4.0 * y + 10.5, clear = False) assert x.getObj() == 1.0 assert y.getObj() == 4.0 assert s.getObjoffset() == 10.5 # add some constraint c = s.addCons(x + 2 * y >= 1.0) assert c.isLinear() s.chgLhs(c, 5.0) s.chgRhs(c, 6.0) assert s.getLhs(c) == 5.0 assert s.getRhs(c) == 6.0 # solve problem s.optimize() solution = s.getBestSol() # print solution assert (s.getVal(x) == s.getSolVal(solution, x)) assert (s.getVal(y) == s.getSolVal(solution, y)) assert round(s.getVal(x)) == 5.0 assert round(s.getVal(y)) == 0.0 assert s.getSlack(c, solution) == 0.0 assert s.getSlack(c, solution, 'lhs') == 0.0 assert s.getSlack(c, solution, 'rhs') == 1.0 assert s.getActivity(c, solution) == 5.0 s.writeProblem('model') s.writeProblem('model.lp') s.freeProb() s = Model() x = s.addVar("x", vtype = 'C', obj = 1.0) y = s.addVar("y", vtype = 'C', obj = 2.0) c = s.addCons(x + 2 * y <= 1.0) s.setMaximize() s.delCons(c) s.optimize() assert s.getStatus() == 'unbounded'
def test_circle(): points =[ (2.802686, 1.398947), (4.719673, 4.792101), (1.407758, 7.769566), (2.253320, 2.373641), (8.583144, 9.769102), (3.022725, 5.470335), (5.791380, 1.214782), (8.304504, 8.196392), (9.812677, 5.284600), (9.445761, 9.541600)] m = Model() a = m.addVar('a', lb=None) b = m.addVar('b', ub=None) r = m.addVar('r') # minimize radius m.setObjective(r, 'minimize') for i,p in enumerate(points): # NOTE: SCIP will not identify this as SOC constraints! m.addCons( sqrt((a - p[0])**2 + (b - p[1])**2) <= r, name = 'point_%d'%i) m.optimize() bestsol = m.getBestSol() assert abs(m.getSolVal(bestsol, r) - 5.2543) < 1.0e-3 assert abs(m.getSolVal(bestsol, a) - 6.1242) < 1.0e-3 assert abs(m.getSolVal(bestsol, b) - 5.4702) < 1.0e-3
def prodmix(I,K,a,p,epsilon,LB): """prodmix: robust production planning using soco Parameters: I - set of materials K - set of components a[i][k] - coef. matrix p[i] - price of material i LB[k] - amount needed for k Returns a model, ready to be solved. """ model = Model("robust product mix") x,rhs = {},{} for i in I: x[i] = model.addVar(vtype="C", name="x(%s)"%i) for k in K: rhs[k] = model.addVar(vtype="C", name="rhs(%s)"%k) model.addCons(quicksum(x[i] for i in I) == 1) for k in K: model.addCons(rhs[k] == -LB[k]+ quicksum(a[i,k]*x[i] for i in I) ) model.addCons(quicksum(epsilon*epsilon*x[i]*x[i] for i in I) <= rhs[k]*rhs[k]) model.setObjective(quicksum(p[i]*x[i] for i in I), "minimize") model.data = x,rhs return model
def markowitz(I,sigma,r,alpha): """markowitz -- simple markowitz model for portfolio optimization. Parameters: - I: set of items - sigma[i]: standard deviation of item i - r[i]: revenue of item i - alpha: acceptance threshold Returns a model, ready to be solved. """ model = Model("markowitz") x = {} for i in I: x[i] = model.addVar(vtype="C", name="x(%s)"%i) # quantity of i to buy model.addCons(quicksum(r[i]*x[i] for i in I) >= alpha) model.addCons(quicksum(x[i] for i in I) == 1) # set nonlinear objective: SCIP only allow for linear objectives hence the following obj = model.addVar(vtype="C", name="objective", lb = None, ub = None) # auxiliary variable to represent objective model.addCons(quicksum(sigma[i]**2 * x[i] * x[i] for i in I) <= obj) model.setObjective(obj, "minimize") model.data = x return model
def mils_echelon(T,K,P,f,g,c,d,h,a,M,UB,phi): """ mils_echelon: echelon formulation for the multi-item, multi-stage lot-sizing problem Parameters: - T: number of periods - K: set of resources - P: set of items - f[t,p]: set-up costs (on period t, for product p) - g[t,p]: set-up times - c[t,p]: variable costs - d[t,p]: demand values - h[t,p]: holding costs - a[t,k,p]: amount of resource k for producing p in period t - M[t,k]: resource k upper bound on period t - UB[t,p]: upper bound of production time of product p in period t - phi[(i,j)]: units of i required to produce a unit of j (j parent of i) """ rho = calc_rho(phi) # rho[(i,j)]: units of i required to produce a unit of j (j ancestor of i) model = Model("multi-stage lotsizing -- echelon formulation") y,x,E,H = {},{},{},{} Ts = range(1,T+1) for p in P: for t in Ts: y[t,p] = model.addVar(vtype="B", name="y(%s,%s)"%(t,p)) x[t,p] = model.addVar(vtype="C", name="x(%s,%s)"%(t,p)) H[t,p] = h[t,p] - sum([h[t,q]*phi[q,p] for (q,p2) in phi if p2 == p]) E[t,p] = model.addVar(vtype="C", name="E(%s,%s)"%(t,p)) # echelon inventory E[0,p] = model.addVar(vtype="C", name="E(%s,%s)"%(0,p)) # echelon inventory for t in Ts: for p in P: # flow conservation constraints dsum = d[t,p] + sum([rho[p,q]*d[t,q] for (p2,q) in rho if p2 == p]) model.addCons(E[t-1,p] + x[t,p] == E[t,p] + dsum, "FlowCons(%s,%s)"%(t,p)) # capacity connection constraints model.addCons(x[t,p] <= UB[t,p]*y[t,p], "ConstrUB(%s,%s)"%(t,p)) # time capacity constraints for k in K: model.addCons(quicksum(a[t,k,p]*x[t,p] + g[t,p]*y[t,p] for p in P) <= M[t,k], "TimeUB(%s,%s)"%(t,k)) # calculate echelon quantities for p in P: model.addCons(E[0,p] == 0, "EchelonInit(%s)"%(p)) for t in Ts: model.addCons(E[t,p] >= quicksum(phi[p,q]*E[t,q] for (p2,q) in phi if p2 == p), "EchelonLB(%s,%s)"%(t,p)) model.setObjective(\ quicksum(f[t,p]*y[t,p] + c[t,p]*x[t,p] + H[t,p]*E[t,p] for t in Ts for p in P), \ "minimize") model.data = y,x,E return model
def _init(): model = Model() model.hideOutput() x = model.addVar("x","B") y = model.addVar("y","B") z = model.addVar("z","B") return model, x, y, z
def mtz_strong(n,c): """mtz_strong: Miller-Tucker-Zemlin's model for the (asymmetric) traveling salesman problem (potential formulation, adding stronger constraints) Parameters: n - number of nodes c[i,j] - cost for traversing arc (i,j) Returns a model, ready to be solved. """ model = Model("atsp - mtz-strong") x,u = {},{} for i in range(1,n+1): u[i] = model.addVar(lb=0, ub=n-1, vtype="C", name="u(%s)"%i) for j in range(1,n+1): if i != j: x[i,j] = model.addVar(vtype="B", name="x(%s,%s)"%(i,j)) for i in range(1,n+1): model.addCons(quicksum(x[i,j] for j in range(1,n+1) if j != i) == 1, "Out(%s)"%i) model.addCons(quicksum(x[j,i] for j in range(1,n+1) if j != i) == 1, "In(%s)"%i) for i in range(1,n+1): for j in range(2,n+1): if i != j: model.addCons(u[i] - u[j] + (n-1)*x[i,j] + (n-3)*x[j,i] <= n-2, "LiftedMTZ(%s,%s)"%(i,j)) for i in range(2,n+1): model.addCons(-x[1,i] - u[i] + (n-3)*x[i,1] <= -2, name="LiftedLB(%s)"%i) model.addCons(-x[i,1] + u[i] + (n-3)*x[1,i] <= n-2, name="LiftedUB(%s)"%i) model.setObjective(quicksum(c[i,j]*x[i,j] for (i,j) in x), "minimize") model.data = x,u return model
def kmedian(I,J,c,k): """kmedian -- minimize total cost of servicing customers from k facilities Parameters: - I: set of customers - J: set of potential facilities - c[i,j]: cost of servicing customer i from facility j - k: number of facilities to be used Returns a model, ready to be solved. """ model = Model("k-median") x,y = {},{} for j in J: y[j] = model.addVar(vtype="B", name="y(%s)"%j) for i in I: x[i,j] = model.addVar(vtype="B", name="x(%s,%s)"%(i,j)) for i in I: model.addCons(quicksum(x[i,j] for j in J) == 1, "Assign(%s)"%i) for j in J: model.addCons(x[i,j] <= y[j], "Strong(%s,%s)"%(i,j)) model.addCons(quicksum(y[j] for j in J) == k, "Facilities") model.setObjective(quicksum(c[i,j]*x[i,j] for i in I for j in J), "minimize") model.data = x,y return model
def p_portfolio(I,sigma,r,alpha,beta): """p_portfolio -- modified markowitz model for portfolio optimization. Parameters: - I: set of items - sigma[i]: standard deviation of item i - r[i]: revenue of item i - alpha: acceptance threshold - beta: desired confidence level Returns a model, ready to be solved. """ model = Model("p_portfolio") x = {} for i in I: x[i] = model.addVar(vtype="C", name="x(%s)"%i) # quantity of i to buy rho = model.addVar(vtype="C", name="rho") rhoaux = model.addVar(vtype="C", name="rhoaux") model.addCons(rho == quicksum(r[i]*x[i] for i in I)) model.addCons(quicksum(x[i] for i in I) == 1) model.addCons(rhoaux == (alpha - rho)*(1/phi_inv(beta))) #todo model.addCons(quicksum(sigma[i]**2 * x[i] * x[i] for i in I) <= rhoaux * rhoaux) model.setObjective(rho, "maximize") model.data = x return model
def gcp(V,E,K): """gcp -- model for minimizing the number of colors in a graph Parameters: - V: set/list of nodes in the graph - E: set/list of edges in the graph - K: upper bound on the number of colors Returns a model, ready to be solved. """ model = Model("gcp") x,y = {},{} for k in range(K): y[k] = model.addVar(vtype="B", name="y(%s)"%k) for i in V: x[i,k] = model.addVar(vtype="B", name="x(%s,%s)"%(i,k)) for i in V: model.addCons(quicksum(x[i,k] for k in range(K)) == 1, "AssignColor(%s)"%i) for (i,j) in E: for k in range(K): model.addCons(x[i,k] + x[j,k] <= y[k], "NotSameColor(%s,%s,%s)"%(i,j,k)) model.setObjective(quicksum(y[k] for k in range(K)), "minimize") model.data = x return model
def vrp(V, c, m, q, Q): """solve_vrp -- solve the vehicle routing problem. - start with assignment model (depot has a special status) - add cuts until all components of the graph are connected Parameters: - V: set/list of nodes in the graph - c[i,j]: cost for traversing edge (i,j) - m: number of vehicles available - q[i]: demand for customer i - Q: vehicle capacity Returns the optimum objective value and the list of edges used. """ model = Model("vrp") vrp_conshdlr = VRPconshdlr() x = {} for i in V: for j in V: if j > i and i == V[0]: # depot x[i,j] = model.addVar(ub=2, vtype="I", name="x(%s,%s)"%(i,j)) elif j > i: x[i,j] = model.addVar(ub=1, vtype="I", name="x(%s,%s)"%(i,j)) model.addCons(quicksum(x[V[0],j] for j in V[1:]) == 2*m, "DegreeDepot") for i in V[1:]: model.addCons(quicksum(x[j,i] for j in V if j < i) + quicksum(x[i,j] for j in V if j > i) == 2, "Degree(%s)"%i) model.setObjective(quicksum(c[i,j]*x[i,j] for i in V for j in V if j>i), "minimize") model.data = x return model, vrp_conshdlr
def create_model(): # create solver instance s = Model() # add some variables x = s.addVar("x", obj = -1.0, vtype = "I", lb=-10) y = s.addVar("y", obj = 1.0, vtype = "I", lb=-1000) z = s.addVar("z", obj = 1.0, vtype = "I", lb=-1000) # add some constraint s.addCons(314*x + 867*y + 860*z == 363) s.addCons(87*x + 875*y - 695*z == 423) # create conshdlr and include it to SCIP conshdlr = MyConshdlr(shouldtrans=True, shouldcopy=False) s.includeConshdlr(conshdlr, "PyCons", "custom constraint handler implemented in python", sepapriority = 1, enfopriority = -1, chckpriority = 1, sepafreq = 10, propfreq = 50, eagerfreq = 1, maxprerounds = -1, delaysepa = False, delayprop = False, needscons = True, presoltiming = SCIP_PRESOLTIMING.FAST, proptiming = SCIP_PROPTIMING.BEFORELP) cons1 = s.createCons(conshdlr, "cons1name") ids.append(id(cons1)) cons2 = s.createCons(conshdlr, "cons2name") ids.append(id(cons2)) conshdlr.createData(cons1, 10, "cons1_anothername") conshdlr.createData(cons2, 12, "cons2_anothername") # add these constraints s.addPyCons(cons1) s.addPyCons(cons2) return s
def gcp_fixed_k(V,E,K): """gcp_fixed_k -- model for minimizing number of bad edges in coloring a graph Parameters: - V: set/list of nodes in the graph - E: set/list of edges in the graph - K: number of colors to be used Returns a model, ready to be solved. """ model = Model("gcp - fixed k") x,z = {},{} for i in V: for k in range(K): x[i,k] = model.addVar(vtype="B", name="x(%s,%s)"%(i,k)) for (i,j) in E: z[i,j] = model.addVar(vtype="B", name="z(%s,%s)"%(i,j)) for i in V: model.addCons(quicksum(x[i,k] for k in range(K)) == 1, "AssignColor(%s)" % i) for (i,j) in E: for k in range(K): model.addCons(x[i,k] + x[j,k] <= 1 + z[i,j], "BadEdge(%s,%s,%s)"%(i,j,k)) model.setObjective(quicksum(z[i,j] for (i,j) in E), "minimize") model.data = x,z return model
def gpp(V,E): """gpp -- model for the graph partitioning problem Parameters: - V: set/list of nodes in the graph - E: set/list of edges in the graph Returns a model, ready to be solved. """ model = Model("gpp") x = {} y = {} for i in V: x[i] = model.addVar(vtype="B", name="x(%s)"%i) for (i,j) in E: y[i,j] = model.addVar(vtype="B", name="y(%s,%s)"%(i,j)) model.addCons(quicksum(x[i] for i in V) == len(V)/2, "Partition") for (i,j) in E: model.addCons(x[i] - x[j] <= y[i,j], "Edge(%s,%s)"%(i,j)) model.addCons(x[j] - x[i] <= y[i,j], "Edge(%s,%s)"%(j,i)) model.setObjective(quicksum(y[i,j] for (i,j) in E), "minimize") model.data = x return model
def weber(I,x,y,w): """weber: model for solving the single source weber problem using soco. Parameters: - I: set of customers - x[i]: x position of customer i - y[i]: y position of customer i - w[i]: weight of customer i Returns a model, ready to be solved. """ model = Model("weber") X,Y,z,xaux,yaux = {},{},{},{},{} X = model.addVar(lb=-model.infinity(), vtype="C", name="X") Y = model.addVar(lb=-model.infinity(), vtype="C", name="Y") for i in I: z[i] = model.addVar(vtype="C", name="z(%s)"%(i)) xaux[i] = model.addVar(lb=-model.infinity(), vtype="C", name="xaux(%s)"%(i)) yaux[i] = model.addVar(lb=-model.infinity(), vtype="C", name="yaux(%s)"%(i)) for i in I: model.addCons(xaux[i]*xaux[i] + yaux[i]*yaux[i] <= z[i]*z[i], "MinDist(%s)"%(i)) model.addCons(xaux[i] == (x[i]-X), "xAux(%s)"%(i)) model.addCons(yaux[i] == (y[i]-Y), "yAux(%s)"%(i)) model.setObjective(quicksum(w[i]*z[i] for i in I), "minimize") model.data = X,Y,z return model
def kcenter(I,J,c,k): """kcenter -- minimize the maximum travel cost from customers to k facilities. Parameters: - I: set of customers - J: set of potential facilities - c[i,j]: cost of servicing customer i from facility j - k: number of facilities to be used Returns a model, ready to be solved. """ model = Model("k-center") z = model.addVar(vtype="C", name="z") x,y = {},{} for j in J: y[j] = model.addVar(vtype="B", name="y(%s)"%j) for i in I: x[i,j] = model.addVar(vtype="B", name="x(%s,%s)"%(i,j)) for i in I: model.addCons(quicksum(x[i,j] for j in J) == 1, "Assign(%s)"%i) for j in J: model.addCons(x[i,j] <= y[j], "Strong(%s,%s)"%(i,j)) model.addCons(c[i,j]*x[i,j] <= z, "Max_x(%s,%s)"%(i,j)) model.addCons(quicksum(y[j] for j in J) == k, "Facilities") model.setObjective(z, "minimize") model.data = x,y return model
def sils(T,f,c,d,h): """sils -- LP lotsizing for the single item lot sizing problem Parameters: - T: number of periods - P: set of products - f[t]: set-up costs (on period t) - c[t]: variable costs - d[t]: demand values - h[t]: holding costs Returns a model, ready to be solved. """ model = Model("single item lotsizing") Ts = range(1,T+1) M = sum(d[t] for t in Ts) y,x,I = {},{},{} for t in Ts: y[t] = model.addVar(vtype="I", ub=1, name="y(%s)"%t) x[t] = model.addVar(vtype="C", ub=M, name="x(%s)"%t) I[t] = model.addVar(vtype="C", name="I(%s)"%t) I[0] = 0 for t in Ts: model.addCons(x[t] <= M*y[t], "ConstrUB(%s)"%t) model.addCons(I[t-1] + x[t] == I[t] + d[t], "FlowCons(%s)"%t) model.setObjective(\ quicksum(f[t]*y[t] + c[t]*x[t] + h[t]*I[t] for t in Ts),\ "minimize") model.data = y,x,I return model
def mils_standard(T,K,P,f,g,c,d,h,a,M,UB,phi): """ mils_standard: standard formulation for the multi-item, multi-stage lot-sizing problem Parameters: - T: number of periods - K: set of resources - P: set of items - f[t,p]: set-up costs (on period t, for product p) - g[t,p]: set-up times - c[t,p]: variable costs - d[t,p]: demand values - h[t,p]: holding costs - a[t,k,p]: amount of resource k for producing p in period t - M[t,k]: resource k upper bound on period t - UB[t,p]: upper bound of production time of product p in period t - phi[(i,j)]: units of i required to produce a unit of j (j parent of i) """ model = Model("multi-stage lotsizing -- standard formulation") y,x,I = {},{},{} Ts = range(1,T+1) for p in P: for t in Ts: y[t,p] = model.addVar(vtype="B", name="y(%s,%s)"%(t,p)) x[t,p] = model.addVar(vtype="C",name="x(%s,%s)"%(t,p)) I[t,p] = model.addVar(vtype="C",name="I(%s,%s)"%(t,p)) I[0,p] = model.addVar(name="I(%s,%s)"%(0,p)) for t in Ts: for p in P: # flow conservation constraints model.addCons(I[t-1,p] + x[t,p] == \ quicksum(phi[p,q]*x[t,q] for (p2,q) in phi if p2 == p) \ + I[t,p] + d[t,p], "FlowCons(%s,%s)"%(t,p)) # capacity connection constraints model.addCons(x[t,p] <= UB[t,p]*y[t,p], "ConstrUB(%s,%s)"%(t,p)) # time capacity constraints for k in K: model.addCons(quicksum(a[t,k,p]*x[t,p] + g[t,p]*y[t,p] for p in P) <= M[t,k], "TimeUB(%s,%s)"%(t,k)) # initial inventory quantities for p in P: model.addCons(I[0,p] == 0, "InventInit(%s)"%(p)) model.setObjective(\ quicksum(f[t,p]*y[t,p] + c[t,p]*x[t,p] + h[t,p]*I[t,p] for t in Ts for p in P), \ "minimize") model.data = y,x,I return model
def test_quicksum_model(): m = Model("quicksum") x = m.addVar("x") y = m.addVar("y") z = m.addVar("z") c = 2.3 q = quicksum([x,y,z,c]) == 0.0 s = sum([x,y,z,c]) == 0.0 assert(q.expr.terms == s.expr.terms)
def setModel(vtype="B", name=None, imax=2): """initialize model and its variables. imax (int): number of operators""" if name is None: name = "model" m = Model(name) m.hideOutput() i = 0 r = m.addVar("r", vtype) while i < imax: m.addVar("v%s" % i, vtype) i += 1 return m
def staff_mo(I,T,N,J,S,c,b): """ staff: staff scheduling Parameters: - I: set of members in the staff - T: number of periods in a cycle - N: number of working periods required for staff's elements in a cycle - J: set of shifts in each period (shift 0 == rest) - S: subset of shifts that must be kept at least consecutive days - c[i,t,j]: cost of a shit j of staff's element i on period t - b[t,j]: number of staff elements required in period t, shift j Returns a model with no objective function. """ Ts = range(1,T+1) model = Model("staff scheduling -- multiobjective version") x,y = {},{} for t in Ts: for j in J: for i in I: x[i,t,j] = model.addVar(vtype="B", name="x(%s,%s,%s)" % (i,t,j)) y[t,j] = model.addVar(vtype="C", name="y(%s,%s)" % (t,j)) C = model.addVar(vtype="C", name="cost") U = model.addVar(vtype="C", name="uncovered") model.addCons(C >= quicksum(c[i,t,j]*x[i,t,j] for i in I for t in Ts for j in J if j != 0), "Cost") model.addCons(U >= quicksum(y[t,j] for t in Ts for j in J if j != 0), "Uncovered") for t in Ts: for j in J: if j == 0: continue model.addCons(quicksum(x[i,t,j] for i in I) >= b[t,j] - y[t,j], "Cover(%s,%s)" % (t,j)) for i in I: model.addCons(quicksum(x[i,t,j] for t in Ts for j in J if j != 0) == N, "Work(%s)"%i) for t in Ts: model.addCons(quicksum(x[i,t,j] for j in J) == 1, "Assign(%s,%s)" % (i,t)) for j in J: if j != 0: model.addCons(x[i,t,j] + quicksum(x[i,t,k] for k in J if k != j and k != 0) <= 1,\ "Require(%s,%s,%s)" % (i,t,j)) for t in range(2,T): for j in S: model.addCons(x[i,t-1,j] + x[i,t+1,j] >= x[i,t,j], "SameShift(%s,%s,%s)" % (i,t,j)) model.data = x,y,C,U return model
def mctransp(I,J,K,c,d,M): """mctransp -- model for solving the Multi-commodity Transportation Problem Parameters: - I: set of customers - J: set of facilities - K: set of commodities - c[i,j,k]: unit transportation cost on arc (i,j) for commodity k - d[i][k]: demand for commodity k at node i - M[j]: capacity Returns a model, ready to be solved. """ model = Model("multi-commodity transportation") # Create variables x = {} for (i,j,k) in c: x[i,j,k] = model.addVar(vtype="C", name="x(%s,%s,%s)" % (i,j,k)) # Demand constraints for i in I: for k in K: model.addCons(sum(x[i,j,k] for j in J if (i,j,k) in x) == d[i,k], "Demand(%s,%s)" % (i,k)) # Capacity constraints for j in J: model.addCons(sum(x[i,j,k] for (i,j2,k) in x if j2 == j) <= M[j], "Capacity(%s)" % j) # Objective model.setObjective(quicksum(c[i,j,k]*x[i,j,k] for (i,j,k) in x), "minimize") model.data = x return model
def eoq_soco(I,F,h,d,w,W): """eoq_soco -- multi-item capacitated economic ordering quantity model using soco Parameters: - I: set of items - F[i]: ordering cost for item i - h[i]: holding cost for item i - d[i]: demand for item i - w[i]: unit weight for item i - W: capacity (limit on order quantity) Returns a model, ready to be solved. """ model = Model("EOQ model using SOCO") T,c = {},{} for i in I: T[i] = model.addVar(vtype="C", name="T(%s)"%i) # cycle time for item i c[i] = model.addVar(vtype="C", name="c(%s)"%i) # total cost for item i for i in I: model.addCons(F[i] <= c[i]*T[i]) model.addCons(quicksum(w[i]*d[i]*T[i] for i in I) <= W) model.setObjective(quicksum(c[i] + h[i]*d[i]*T[i]*0.5 for i in I), "minimize") model.data = T,c return model
def transp(I,J,c,d,M): """transp -- model for solving the transportation problem Parameters: I - set of customers J - set of facilities c[i,j] - unit transportation cost on arc (i,j) d[i] - demand at node i M[j] - capacity Returns a model, ready to be solved. """ model = Model("transportation") # Create variables x = {} for i in I: for j in J: x[i,j] = model.addVar(vtype="C", name="x(%s,%s)" % (i, j)) # Demand constraints for i in I: model.addCons(quicksum(x[i,j] for j in J if (i,j) in x) == d[i], name="Demand(%s)" % i) # Capacity constraints for j in J: model.addCons(quicksum(x[i,j] for i in I if (i,j) in x) <= M[j], name="Capacity(%s)" % j) # Objective model.setObjective(quicksum(c[i,j]*x[i,j] for (i,j) in x), "minimize") model.optimize() model.data = x return model
def test_lpi(): # create LP instance myLP = LP() myLP.addRow(entries = [(0,1),(1,2)] ,lhs = 5) lhs, rhs = myLP.getSides() assert lhs[0] == 5.0 assert rhs[0] == myLP.infinity() assert(myLP.ncols() == 2) myLP.chgObj(0, 1.0) myLP.chgObj(1, 2.0) solval = myLP.solve() # create solver instance s = Model() # add some variables x = s.addVar("x", obj=1.0) y = s.addVar("y", obj=2.0) # add some constraint s.addCons(x + 2*y >= 5) # solve problem s.optimize() # check solution assert round(s.getVal(x)) == 5.0 assert round(s.getVal(y)) == 0.0 assert round(s.getObjVal() == solval)
def maxflow(V,M,source,sink): """maxflow: maximize flow from source to sink, taking into account arc capacities M Parameters: - V: set of vertices - M[i,j]: dictionary or capacity for arcs (i,j) - source: flow origin - sink: flow target Returns a model, ready to be solved. """ # create max-flow underlying model, on which to find cuts model = Model("maxflow") f = {} # flow variable for (i,j) in M: f[i,j] = model.addVar(lb=-M[i,j], ub=M[i,j], name="flow(%s,%s)"%(i,j)) cons = {} for i in V: if i != source and i != sink: cons[i] = model.addCons( quicksum(f[i,j] for j in V if i<j and (i,j) in M) - \ quicksum(f[j,i] for j in V if i>j and (j,i) in M) == 0, "FlowCons(%s)"%i) model.setObjective(quicksum(f[i,j] for (i,j) in M if i==source), "maximize") # model.write("tmp.lp") model.data = f,cons return model
def mctransp(I,J,K,c,d,M): """mctransp -- model for solving the Multi-commodity Transportation Problem Parameters: - I: set of customers - J: set of facilities - K: set of commodities - c[i,j,k]: unit transportation cost on arc (i,j) for commodity k - d[i][k]: demand for commodity k at node i - M[j]: capacity Returns a model, ready to be solved. """ model = Model("multi-commodity transportation") # Create variables x = {} for (i,j,k) in c: x[i,j,k] = model.addVar(vtype="C", name="x(%s,%s,%s)" % (i,j,k), obj=c[i,j,k]) # todo arcs = tuplelist([(i,j,k) for (i,j,k) in x]) # Demand constraints for i in I: for k in K: model.addCons(sum(x[i,j,k] for (i,j,k) in arcs.select(i,"*",k)) == d[i,k], "Demand(%s,%s)" % (i,k)) # Capacity constraints for j in J: model.addConstr(sum(x[i,j,k] for (i,j,k) in arcs.select("*",j,"*")) <= M[j], "Capacity(%s)" % j) model.data = x return model
def test_event(): # create solver instance s = Model() s.hideOutput() s.setPresolve(SCIP_PARAMSETTING.OFF) eventhdlr = MyEvent() s.includeEventhdlr(eventhdlr, "TestFirstLPevent", "python event handler to catch FIRSTLPEVENT") # add some variables x = s.addVar("x", obj=1.0) y = s.addVar("y", obj=2.0) # add some constraint s.addCons(x + 2*y >= 5) # solve problem s.optimize() # print solution assert round(s.getVal(x)) == 5.0 assert round(s.getVal(y)) == 0.0 del s assert 'eventinit' in calls assert 'eventexit' in calls assert 'eventexec' in calls assert len(calls) == 3
def tsp(V,c): """tsp -- model for solving the traveling salesman problem with callbacks - start with assignment model - add cuts until there are no sub-cycles Parameters: - V: set/list of nodes in the graph - c[i,j]: cost for traversing edge (i,j) Returns the optimum objective value and the list of edges used. """ model = Model("TSP_lazy") conshdlr = TSPconshdlr() x = {} for i in V: for j in V: if j > i: x[i,j] = model.addVar(vtype = "B",name = "x(%s,%s)" % (i,j)) for i in V: model.addCons(quicksum(x[j, i] for j in V if j < i) + quicksum(x[i, j] for j in V if j > i) == 2, "Degree(%s)" % i) model.setObjective(quicksum(c[i, j] * x[i, j] for i in V for j in V if j > i), "minimize") model.data = x return model, conshdlr
def create_sudoku(): scip = Model("Sudoku") x = {} # values of squares for row in range(9): for col in range(9): # some variables are fix if init[row*9 + col] != 0: x[row,col] = scip.addVar(vtype = "I", lb = init[row*9 + col], ub = init[row*9 + col], name = "x(%s,%s)" % (row,col)) else: x[row,col] = scip.addVar(vtype = "I", lb = 1, ub = 9, name = "x(%s,%s)" % (row,col)) var = x[row,col] #print("built var ", var.name, " with bounds: (%d,%d)"%(var.getLbLocal(), var.getUbLocal())) conshdlr = ALLDIFFconshdlr() # hoping to get called when all vars have integer values scip.includeConshdlr(conshdlr, "ALLDIFF", "All different constraint", propfreq = 1, enfopriority = -10, chckpriority = -10) # row constraints; also we specify the domain of all variables here # TODO/QUESTION: in principle domain is of course associated to the var and not the constraint. it should be "var.data" # But ideally that information would be handle by SCIP itself... the reason we can't is because domain holes is not implemented, right? domains = {} for row in range(9): vars = [] for col in range(9): var = x[row,col] vars.append(var) vals = set(range(int(round(var.getLbLocal())), int(round(var.getUbLocal())) + 1)) domains[var.ptr()] = vals # this is kind of ugly, isn't it? cons = scip.createCons(conshdlr, "row_%d" % row) #print("in test: received a constraint with id ", id(cons)) ### DELETE cons.data = SimpleNamespace() # so that data behaves like an instance of a class (ie, cons.data.whatever is allowed) cons.data.vars = vars cons.data.domains = domains scip.addPyCons(cons) # col constraints for col in range(9): vars = [] for row in range(9): var = x[row,col] vars.append(var) cons = scip.createCons(conshdlr, "col_%d"%col) cons.data = SimpleNamespace() cons.data.vars = vars cons.data.domains = domains scip.addPyCons(cons) # square constraints for idx1 in range(3): for idx2 in range(3): vars = [] for row in range(3): for col in range(3): var = x[3*idx1 + row, 3*idx2 + col] vars.append(var) cons = scip.createCons(conshdlr, "square_%d-%d"%(idx1, idx2)) cons.data = SimpleNamespace() cons.data.vars = vars cons.data.domains = domains scip.addPyCons(cons) #scip.setObjective() return scip, x
(4, 1): 8, (4, 2): 5, (4, 3): 3, (5, 1): 10, (5, 2): 8, (5, 3): 4, } model = Model("transportation") # Create variables x = {} for i in I: for j in J: x[i, j] = model.addVar(vtype="C", name="x(%s,%s)" % (i, j)) # Demand constraints for i in I: model.addCons(quicksum(x[i, j] for j in J if (i, j) in x) == d[i], name="Demand(%s)" % i) # Capacity constraints for j in J: model.addCons(quicksum(x[i, j] for i in I if (i, j) in x) <= M[j], name="Capacity(%s)" % j) # Objective model.setObjective(quicksum(c[i, j] * x[i, j] for (i, j) in x), "minimize") model.optimize()
from pyscipopt import Model model = Model("Example") # model name is optional x = model.addVar("x") y = model.addVar("y", vtype="INTEGER") model.setObjective(x + y) model.addCons(2 * x - y * y >= 0) model.optimize()
def mintreeMFP(n, e, d): """ mintreeMFP: min Cost Tree based on Flow Conservation Parameters: - n: number of nodes - e[i,j]['cap','cost']: edges of graph, 'cap': capacity of edge, 'cost': cost for traversing edge (i,j) - d[i,j]: demande(data) from node i to j Returns a model, ready to be solved. """ print("\n========min Cost Tree based on Flow Conservation======") model = Model("mintreeMFP") x, f, z = {}, {}, {} # flow variable """ In our model, f[i,j] is the sum of flow on edge, if f[i,j]>0 then z[i,j]=1 else z[i,j]=0, such that get minTree In order to express the logical constraint, define a Big M, and z is Binary, z[i,j]>=f[i,j]/M (gurantee f/M <1) and z[i,j]<=f[i,j]*M (gurantee f[i,j]*M >1) """ M = 100000000 for (i, j) in e.keys(): f[i, j] = model.addVar(ub=1000000, lb=0, vtype="C", name="f[%s,%s]" % (i, j)) z[i, j] = model.addVar(ub=1, lb=0, vtype="B", name="z[%s,%s]" % (i, j)) for (s, t) in d.keys(): x[i, j, s, t] = model.addVar(ub=1000000, lb=0, vtype="C", name="x[%s,%s,%s,%s]" % (i, j, s, t)) # node flow conservation for (s, t) in d.keys(): for j in n.keys(): # for destination node if j == t: model.addCons( quicksum(x[i, j, s, t] for i in n.keys() if (i, j) in e.keys()) - quicksum(x[j, i, s, t] for i in n.keys() if (j, i) in e.keys()) == d[s, t], "DesNode(%s)" % j) # for source node elif j == s: model.addCons( quicksum(x[i, j, s, t] for i in n.keys() if (i, j) in e.keys()) - quicksum(x[j, i, s, t] for i in n.keys() if (j, i) in e.keys()) == -d[s, t], "SourceNode(%s)" % j) else: model.addCons( quicksum(x[i, j, s, t] for i in n.keys() if (i, j) in e.keys()) - quicksum(x[j, i, s, t] for i in n.keys() if (j, i) in e.keys()) == 0, "SourceNode(%s)" % j) # constrains for edge capacity, take into consideration of tree optimization, using variable f for (i, j) in e.keys(): f[i, j] = quicksum(x[i, j, s, t] for (s, t) in d.keys()) model.addCons(f[i, j] <= e[i, j]['cap'], 'edge(%s,%s)' % (i, j)) # logical constraint model.addCons(M * z[i, j] >= f[i, j]) model.addCons(z[i, j] <= f[i, j] * M) model.data = x, f #model.setObjective(quicksum(f[i,j]*e[i,j]['cost'] for (i,j) in e.keys()), "minimize") model.setObjective(quicksum(z[i, j] for (i, j) in e.keys()), "minimize") return model
def scipfamily9generalmini(ll,fixer,one): biggig=[] l = [x for x in constraints()] p = [x for x in allsets()] weight=[1.0,1.0,-1.0] oweight=[1.0,-1.0] for i in range(len(l)): new=l[i] + weight c = [6,6,6,6,6,5,6,7,9] cone = [0,100,41,39,40,27,89,91,111] if fixer == 1: two1 = filtersets.zerone(ll) else: two1 = ll two = [] for i in range(len(two1)): if i != one: two.insert(0,two1[i]) sets=two indexkeeps = filtersets.powerset(9) allones=[1.0]*len(p) flag=1 count=0 index=[] fixf = Model() fixf.hideOutput() fixf.setMinimize() FranklVarsf = [] FvarNamesf = [] FvarBaseNamef = "Setfix" # add frankl variables for i in range(len(p)): FvarNamesf.append(FvarBaseNamef + "_" + str(i)) FranklVarsf.append(fixf.addVar(FvarNamesf[i], vtype='B', obj=1.0, ub=1.0)) # add union-closed constraints for i in range(len(l)): new=l[i] + weight coeffs = {FranklVarsf[l[i][j]-1]: new[j+3] for j in range(0,len(weight))} fixf.addCons(coeffs, lhs=None, rhs=1.0, name ="uc(%s)" %i) # add fixed family for i in range(len(sets)): coeffs = {FranklVarsf[p.index(sets[i])]: 1.0} fixf.addCons(coeffs, lhs = 1.0, rhs = 1.0) # if i >=6 and i <=7: # coeffs = {FranklVars[p.index(sets[i])]: 1.0} # sbin.addCons(coeffs, lhs = 1.0, rhs = 1.0) # add the empty set #fixf.writeProblem('original.lp') fixf.optimize() fixedfam=[0.0]*len(p) if fixf.getStatus()=="optimal": for j in range(len(p)): fixedfam[j]=round(fixf.getVal(FranklVarsf[j])) else: print 'We have a bug in the generation of the fixed family' lf = [x for x in constraintsf(fixedfam)] onemore = [] for i in range(len(fixedfam)): if fixedfam[i] > 0.5: onemore.insert(0,indexkeeps.index(p[i])) print onemore #print [x for x in p if fixedfam[p.index(x)] > 0.0] #return 0 fixf.free() while flag==1: # continous model for c_is slin = Model() slin.hideOutput() # binary model for fixed c_i sbin = Model() sbin.setMinimize() #sbin.setIntParam("limits/solutions", 1) sbin.hideOutput() #sbin.setMaximize() # continous variables c_is WeightVars = [] WvarNames = [] WvarBaseName = "Weight" # binary variables for sets in frankl family FranklVars = [] FvarNames = [] FvarBaseName = "x" # add c_i variables for i in range(len(c)): if i <=7: WvarNames.append(WvarBaseName + "_"+ str(i)) WeightVars.append(slin.addVar(WvarNames[i], vtype='I', obj=1.0, lb=0.0)) else: WvarNames.append(WvarBaseName + "_" + str(i)) WeightVars.append(slin.addVar(WvarNames[i], vtype='I', obj=1.0, lb=0.0)) # add constraints sum equals one coeffs = [1]*len(c) #coeffs1 = [1] objec = {WeightVars[i]: coeffs[i] for i in range(len(c))} slin.setObjective(objec,"minimize") coeffss = {WeightVars[i]: 1.0 for i in range(len(c))} #coeffss1 = {WeightVars[i]: 1.0 for i in range(5,6)} slin.addCons(coeffss, lhs=1.0, rhs=None,name= 'sum_one') #slin.addCons(coeffss1,lhs=0.0, rhs=0.0,name= 'fix_one') if count >= 1: print count # print 'this is it!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1' #print makeccoff(index[0]) # print index[0] # print 'this is it!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1' # print index for i in range(len(index)): size=sum(index[i]) print size print 'hereererere' keeperset=[] for j in range(len(index[i])): if index[i][j] >= 0.5: keeperset.insert(0,j) print count print [indexkeeps.index(p[x]) for x in keeperset] cr=[x for x in makeccoff(index[i])] coeffs = {WeightVars[j]: (2*cr[j]-size) for j in range(len(cr))} slin.addCons(coeffs, lhs=0.0, rhs=None,name= 'nogoodcut') # optimize linear program with c_is # slin.hideOutput() slin.optimize() # get best solution # csol=slin.getBestSol if slin.getStatus()=="optimal": # if we find optimal print c for i in range(len(c)): c[i]=slin.getVal(WeightVars[i]) #print c else: flag=0 # otherwise we found a proof! print 'Found Infeasibility' slin.writeProblem('check.lp') for i in range(len(c)): c[i]=slin.getVal(WeightVars[i]) print c return 0 slin.free() # add frankl variables for i in range(len(p)): FvarNames.append(FvarBaseName + "_" + str(i)) FranklVars.append(sbin.addVar(FvarNames[i], vtype='B', obj=1.0, ub=1.0)) # add union-closed constraints for i in range(len(l)): new=l[i] + weight coeffs = {FranklVars[l[i][j]-1]: new[j+3] for j in range(0,len(weight))} sbin.addCons(coeffs, lhs=None, rhs=1.0, name ="uc(%s)" %i) coeffs = {FranklVars[i]: allones[i] for i in range(len(p))} #sbin.addCons(coeffs, lhs=1, rhs=None, name= 'mini') # add fixed family constraints for i in range(len(lf)): new=lf[i] + oweight coeffs = {FranklVars[lf[i][j]-1]: new[j+2] for j in range(0,len(oweight))} sbin.addCons(coeffs, lhs=None, rhs=0.0, name= "fs(%s)" %i) #weits=makeweightint(c) #num=weits[0] num=[x for x in makeweightint(c)] obj=[x for x in makeobj(c)] # print num # add feasibility constraint coeffs = {FranklVars[i]: num[i] for i in range(len(p))} obj = {FranklVars[i]: obj[i] for i in range(len(p))} sbin.setObjective(obj,"maximize") sbin.addCons(coeffs, lhs = None, rhs = -1) sbin.setMaximize() sbin.writeProblem('checkIP.lp') spx = cplex.Cplex() spx.read('checkIP.lp') #spx.parameters.mip.limits.solutions.set(1) spx.set_log_stream(None) spx.set_error_stream(None) spx.set_warning_stream(None) spx.set_results_stream(None) spx.solve() # optimize binary program # sbin.setMaximize() # sbin.optimize() row=[None]*len(p) if spx.solution.get_status() == 101 or spx.solution.get_status() == 102: for j in range(len(p)): row[j]=round(spx.solution.get_values(j)) index.insert(0,row) else: print 'We found the suckers!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' # we found a proof! print c print [Fraction(x).limit_denominator() for x in c] sbin.writeProblem('checkIP.lp') kepme= [Fraction(x).limit_denominator().numerator for x in c] print kepme print 'werrrerrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr' biggig.insert(0,one) flag = 0 count=count+1 sbin.free() print biggig
from pyscipopt import Model model = Model("Simple linear optimization") x = model.addVar(vtype="I", name="x") y = model.addVar(vtype="I", name="y") z = model.addVar(vtype="I", name="x") model.addCons(x + y + z == 32, "Heads") model.addCons(2 * x + 4 * y + 8 * z == 80, "Legs") model.setObjective(y + z, "minimize") model.optimize() if model.getStatus() == "optimal": print("Optimal value:", model.getObjVal()) print("Solution:") print(" x = ", model.getVal(x)) print(" y = ", model.getVal(y)) print(" z = ", model.getVal(z)) else: print("Problem could not be solved to optimality")
c2[(i, j)] = 2 for j in range(n): I[j] = d[(0, j)] * (random.random() + 0.8) M = list(range(m + 1)) N = I.keys() w = {} x = {} y = {} model = Model('Allocation') for i in M: for j in N: w[i, j] = model.addVar(vtype='C', lb=0.0, name='w(%s,%s)' % (i, j)) for i in M[1:]: for j in N: x[i, j] = model.addVar(vtype='B', name='x(%s,%s)' % (i, j)) for i in M: for j in N: y[i, j] = model.addVar(vtype='C', lb=0.0, name='y(%s,%s)' % (i, j)) # Capacity constraints model.addCons(sum(x[i, j] for i in M[1:] for j in N) <= L, name='Capacity') # Weights constraints for j in N: model.addCons(sum(w[i, j] for i in M) <= 1,
def flp(I,J,d,M,f,c,cp,cU): """flp -- model for the capacitated facility location problem Parameters: - I: set of customers - J: set of facilities - d[i]: demand for customer i - M[j]: capacity of facility j - f[j]: fixed cost for using a facility in point j - c[i,j]: unit cost of servicing demand point i from facility j Returns a model, ready to be solved. """ model = Model("flp") x,y,y2 = {},{},{} for j in range(len(J)): y[j] = model.addVar(vtype="B", name="y(%s)"%j) for i in range(I): x[i,j] = model.addVar(vtype="C", name="x(%s,%s)"%(i,j)) y2[i,j] = model.addVar(vtype="B", name="y2(%s,%s)"%(i,j)) #### restrictions: #### #demand has to be completely served by the facilities for i in range(I): model.addCons(quicksum(x[i,j]*y2[i,j]\ for j in range(len(J))) == d[i]) #demand served by a facility is not allowed to exceed #the capacity of it for j in range(len(M)): model.addCons(quicksum(x[i,j]*y2[i,j]\ for i in range(I)) <= M[j]*y[j]) #delivery to customer is not allowed to exceed customers demand for (i,j) in x: model.addCons(x[i,j]*y2[i,j] <= d[i]*y[j]) for i in range(I): #i = 0 for j in J: #j = 0 model.addCons(y2[i,j] <= y[j]) ####objective function: variable cost for open station ##### #### plus cost for deliveries ###### model.setObjective( # quicksum(f[j]*y[j] for j in J) + quicksum(c[i+3,j]*x[i,j]*cU for i in range(I) for j in J) + quicksum(y[j]*((instance['deport%d' %(j)]['due_time']-\ instance['deport%d' %(j)]['ready_time'])*cp)\ for j in range(len(J))),"minimize") #for the possibility to get access to the values of each #defined variable model.data = x,y,y2 return model
alpha = 0.1 theta = 0.2 p = 1 n = 500 D = {} SV = {0: [120, 30], 1: [40, 10], 2: [40, 10], 3: [40, 10]} for i in range(m + 1): D[i] = np.clip(np.random.normal(SV[i][0], SV[i][1], n), 1, None) model = Model('Allocation') w = {} for i in range(m + 1): w[i] = model.addVar(vtype='C', lb=0.0, ub=1.0, name='DC%i_reserve_ratio' % i) x = {} for i in range(m + 1): for j in range(n): x[(i, j)] = model.addVar(vtype='C', lb=0.0, name='DC%i_stockout' % i) for j in range(n): model.addCons( x[(0,j)] >= (1-alpha) * (1-theta) * quicksum(x[(i,j)]\ for i in range(1,m+1)) - w[0] * I[0] + D[0][j], name='RDC_out') for i in range(1, m + 1): for j in range(n): model.addCons(x[(i, j)] >= D[i][j] - w[i] * I[0] - I[i], name='FDC%i_out' % i)
class KS_MIP(MIPModel): """ KS: the knapsack instance fss: first_stage_solution scenario: the sampled scenario to be modeled. model the MIP """ def __init__(self, ks, fss, sampled_weights): MIPModel.__init__(self) self.value = ks.get_values() self.penalty = ks.get_penalty() self.weight = sampled_weights self.capacity = ks.get_C() assert (len(fss) == len(self.value)) self.x_star = fss self.model = Model("knap_sasck") self.solution = None self.slack = None self.opt_obj = None def solve(self): self.best_sol_list = [] # Create variables y = {} # auxiliary variables # ax = {} for i in range(len(self.value)): y[i] = self.model.addVar(vtype="B", name="y(%s)" % i) # ax[i] = self.model.addVar(vtype="B", name="ax(%s)" % i) slack = self.model.addVar(vtype="C", name="slack") # Add constraints self.model.addCons( quicksum(self.weight[j] * (self.x_star[j] - y[j]) for j in range(len(self.weight))) <= self.capacity, name="capacity constraint") for j in range(len(self.value)): self.model.addCons(y[j] <= self.x_star[j]) # impose ax[i] = max (y-x,0) api does not support min, max function self.model.setObjective( quicksum(-1 * self.value[j] * y[j] + y[j] * (-1 * self.penalty) for j in range(len(self.value))), "maximize") self.model.data = y, slack self.model.hideOutput() # silent the output self.model.optimize() status = self.model.getStatus() if status == "unbounded" or status == "infeasible": return status y, slack = self.model.data Y = np.zeros(len(self.weight)) for i in range(len(self.weight)): Y[i] = self.model.getVal(y[i]) self.solution, self.slack, self.opt_obj = Y, self.model.getVal( slack), self.model.getObjVal() return status def query_solution(self): return self.solution def query_slack(self): return self.slack def query_opt_obj(self): return self.opt_obj def query_best_sol(self): return self.best_sol_list
Item(4, 36, 50), Item(5, 36, 35), Item(6, 48, 30), Item(7, 42, 15), Item(8, 42, 40), Item(9, 36, 30), Item(10, 24, 35), Item(11, 30, 45), Item(12, 30, 10), Item(13, 42, 20), Item(14, 36, 30), Item(15, 36, 25) ] bins = [ Bin(1, 100), Bin(2, 100), Bin(3, 100), Bin(4, 100), Bin(5, 100) ] model = Model() x = dict() for _item in items: for _bin in bins: x[_item.index, _bin.index] = model.addVar(vtype="B") for _item in items: model.addCons( quicksum(x[_item.index, _bin.index] for _bin in bins) <= 1) for _bin in bins: model.addCons( quicksum( _item.weight * x[_item.index, _bin.index] for _item in items ) <= _bin.capacity) model.setObjective( quicksum( _item.value * x[_item.index, _bin.index] for _item in items for _bin in bins
def test_string(): PI = 3.141592653589793238462643 NWIRES = 11 DIAMETERS = [ 0.207, 0.225, 0.244, 0.263, 0.283, 0.307, 0.331, 0.362, 0.394, 0.4375, 0.500 ] PRELOAD = 300.0 MAXWORKLOAD = 1000.0 MAXDEFLECT = 6.0 DEFLECTPRELOAD = 1.25 MAXFREELEN = 14.0 MAXCOILDIAM = 3.0 MAXSHEARSTRESS = 189000.0 SHEARMOD = 11500000.0 m = Model() coil = m.addVar('coildiam') wire = m.addVar('wirediam') defl = m.addVar('deflection', lb=DEFLECTPRELOAD / (MAXWORKLOAD - PRELOAD), ub=MAXDEFLECT / PRELOAD) ncoils = m.addVar('ncoils', vtype='I') const1 = m.addVar('const1') const2 = m.addVar('const2') volume = m.addVar('volume') y = [m.addVar('wire%d' % i, vtype='B') for i in range(NWIRES)] obj = 1.0 * volume m.setObjective(obj, 'minimize') m.addCons(PI / 2 * (ncoils + 2) * coil * wire**2 - volume == 0, name='voldef') m.addCons(coil / wire - const1 == 0, name='defconst1') m.addCons((4.0 * const1 - 1.0) / (4.0 * const1 - 4.0) + 0.615 / const1 - const2 == 0, name='defconst2') m.addCons(8.0 * MAXWORKLOAD / PI * const1 * const2 - MAXSHEARSTRESS * wire**2 <= 0.0, name='shear') m.addCons(8.0 / SHEARMOD * ncoils * const1**3 / wire - defl == 0.0, name="defdefl") m.addCons( MAXWORKLOAD * defl + 1.05 * ncoils * wire + 2.1 * wire <= MAXFREELEN, name='freel') m.addCons(coil + wire <= MAXCOILDIAM, name='coilwidth') m.addCons(quicksum(c * v for (c, v) in zip(DIAMETERS, y)) - wire == 0, name='defwire') m.addCons(quicksum(y) == 1, name='selectwire') m.optimize() assert abs(m.getPrimalbound() - 1.6924910128) < 1.0e-6
def model(): m = Model() x = m.addVar("x") y = m.addVar("y") z = m.addVar("z") return m, x, y, z
from pyscipopt import Model m = Model("svm") x = m.addVar(vtype='B', name='x') y = m.addVar(vtype='C', name='y') m.addCons(3 * x + 2 * y >= 4) m.optimize()
def optimize(): global n, m, facility, customer model = Model("Facility") model.hideOutput() model.setRealParam('limits/time', 3600) # define decision variable x = [] #bool flag is facility i is serving customer j x = [[0 for x in range(m)] for y in range(n)] o = [0 for x in range(n)] #x[i][j] jth customer is assigned to ith warehouse for i in range(n): for j in range(m): x[i][j] = model.addVar( vtype="B", name="%s,%s" % (i, j)) # whether facility i is serving customer j # each warehouse whether its open or not. for i in range(n): o[i] = model.addVar(vtype="B", name="o(%s)" % (i)) # define constraints # Each customer is exactly assigned to 1 facility for i in range(m): model.addCons(quicksum(x[j][i] for j in range(n)) == 1) #Each facility is serving to its demand for i in range(n): model.addCons( quicksum(x[i][j] * customer[j].demand for j in range(m)) <= facility[i].capacity) # If facility is closed, no customer is assigned to it for i in range(n): for j in range(m): model.addCons(x[i][j] <= o[i]) # if a facility is open , it should have at-least 1 customer. model.addCons( quicksum(x[i][j] for j in range(m) for i in range(n) if o[i]) >= 1) # define objective function model.setObjective( quicksum(o[i] * facility[i].cost + quicksum(x[i][j] * d[i][j] for j in range(m)) for i in range(n)), "minimize") model.setHeuristics(SCIP_PARAMSETTING.AGGRESSIVE) model.optimize() status = model.getStatus() if status == 'optimal': print("%s 1" % (model.getObjVal())) else: print("%s 0" % (model.getObjVal())) ''' cost = 0 if status == 'optimal': for v in model.getVars(): if v.name != "n": print("%s: %d" % (v, round(model.getVal(v)))) else: print("* No variable is printed if model status is not optimal") ''' res = [] res = [0 for x in range(m)] for i in range(n): for j in range(m): if model.getVal(x[i][j]) > EPS: res[int(str(x[i][j]).split(',')[1])] = int( str(x[i][j]).split(',')[0]) #if(i==186): # print ("%s %d %s %d %d" %(model.getVal(x[i][j]), round(model.getVal(x[i][j])), str(x[i][j]), int(str(x[i][j]).split(',')[0]), int(str(x[i][j]).split(',')[1]))) for j in range(m): print(res[j], end=" ") '''
def maxConcurrentMFP(n, e, d, st): """ maxConcurrentMFP: max concurrent multi-commodity flow Problem Parameters: - n: number of nodes - e[i,j]['cap','cost']: edges of graph, 'cap': capacity of edge, 'cost': cost for traversing edge (i,j) - d[i,j]: demande from node i to j Returns a model, ready to be solved. """ print("\n========concurrent multi-commodity flow Problem======") model = Model("maxConcurrentMFP") x, m = {}, {} # flow variable lamba = model.addVar(ub=1000000, lb=1.0, vtype="C", name="lamba") for (i, j) in e.keys(): # f[i, j] = model.addVar(ub=100000000000, lb=0, vtype="I", name="f[%s,%s]" % (i, j)) # z[i, j] = model.addVar(ub=1, lb=0, vtype="B", name="z[%s,%s]" % (i, j)) for s in d.keys(): # ture flow m[i, j, s] = model.addVar(ub=100000000000, lb=0, vtype='C', name="m[%s,%s,%s]" % (i, j, s)) for t in st[s]: # presudo flow x[i, j, s, t] = model.addVar(ub=100000000, lb=0, vtype="C", name="x[%s,%s,%s,%s]" % (i, j, s, t)) # model.addCons(x[i, j, s, t] <= e[i, j]['cap'], 'edges(%s, %s)' % (i, j)) # f[i, j] = quicksum(x[i, j, s, t] for (s, t) in d.keys()) # commodity flow conservation for (i, j) in e.keys(): for s in st.keys(): for t in st[s]: model.addCons(x[i, j, s, t] <= m[i, j, s], 'edges(%s, %s, %s)' % (i, j, s)) # node flow conservation # for destination node if j == t: model.addCons( quicksum(m[i, j, s] for i in n.keys() if (i, j) in e.keys()) - quicksum(m[j, i, s] for i in n.keys() if (j, i) in e.keys()) == lamba * d[s], "DesNode(%s)" % j) # for source node elif j == s: model.addCons( quicksum(m[i, j, s] for i in n.keys() if (i, j) in e.keys()) - quicksum(m[j, i, s] for i in n.keys() if (j, i) in e.keys()) == -lamba * d[s], "SourceNode(%s)" % j) # for relay node else: model.addCons( quicksum(x[i, j, s, t] for i in n.keys() if (i, j) in e.keys()) - quicksum(x[j, i, s, t] for i in n.keys() if (j, i) in e.keys()) == 0, "InterNode(%s)" % j) # constrains for edge capacity, take into consideration of tree optimization, using variable f for (i, j) in e.keys(): # f[i, j] = quicksum(x[i, j, s, t] for (s, t) in d.keys()) model.addCons( quicksum(m[i, j, s] for s in st.keys()) <= e[i, j]['cap'], 'edge(%s,%s)' % (i, j)) # logical constraint # model.addCons(M * z[i, j] >= f[i, j]) # model.addCons(z[i, j] <= f[i, j] * M) model.data = m # model.setObjective(quicksum(f[i,j]*e[i,j]['cost'] for (i,j) in e.keys()), "minimize") model.setObjective(lamba, "maximize") return model
import os from shutil import copyfile from pyscipopt import Model model = Model("Extension") # model name is optional a = model.addVar("a", vtype="CONTINUOUS") b = model.addVar("b", vtype="CONTINUOUS") c = model.addVar("c", vtype="CONTINUOUS") o = model.addVar("o", vtype="CONTINUOUS") tests = ["extension_test1"] for test in tests: #me traigo el caso de test y le pongo de nombre input_B e input_N copyfile(os.path.join("tests","extension",test+"_B.txt"), "input_B.txt") copyfile(os.path.join("tests","extension",test+"_N.txt"), "input_N.txt") #Cargo en SCIP el problema en formato ZIMPL model.readProblem("extension.zpl") model.optimize() sol = model.getBestSol() #Busco solucion e imprimo puntos blanco = open('input_B.txt', 'r').read() negro = open('input_N.txt', 'r').read() print("\n\n###############################################") print("Test "+test+":\n") print("Blanco: \n"+blanco) print("Negro: \n"+negro+"\n") print("Solucion:") print("a: {}".format(sol[a])) print("b: {}".format(sol[b])) print("c: {}".format(sol[c])) print("o: {}".format(sol[o]))
"""prints results""" print("* %s *" % name) objSet = bool(m.getObjective().terms.keys()) print("* Is objective set? %s" % objSet) if objSet: print("* Sense: %s" % m.getObjectiveSense()) for v in m.getVars(): if v.name != "n": print("%s: %d" % (v, round(m.getVal(v)))) print("\n") # AND model = Model() model.hideOutput() x = model.addVar("x", "B") y = model.addVar("y", "B") z = model.addVar("z", "B") r = model.addVar("r", "B") model.addConsAnd([x, y, z], r) model.addCons(x == 1) model.setObjective(r, sense="minimize") model.optimize() printFunc("AND", model) # OR model = Model() model.hideOutput() x = model.addVar("x", "B") y = model.addVar("y", "B") z = model.addVar("z", "B")
def parity(number): """ Prints if a value is even/odd/neither per each value in a example list This example is made for newcomers and motivated by: - modulus is unsupported for pyscipopt.scip.Variable and int - variables are non-integer by default Based on this: #172#issuecomment-394644046 Args: number: value which parity is checked Returns: sval: 1 if number is odd, 0 if number is even, -1 if neither """ sval = -1 if verbose: print(80 * "*") try: assert number == int(round(number)) m = Model() m.hideOutput() # x and n are integer, s is binary # Irrespective to their type, variables are non-negative by default # since 0 is the default lb. To allow for negative values, give None # as lower bound. # (None means -infinity as lower bound and +infinity as upper bound) x = m.addVar("x", vtype="I", lb=None, ub=None) #ub=None is default n = m.addVar("n", vtype="I", lb=None) s = m.addVar("s", vtype="B") # CAVEAT: if number is negative, x's lower bound must be None # if x is set by default as non-negative and number is negative: # there is no feasible solution (trivial) but the program # does not highlight which constraints conflict. m.addCons(x == number) # minimize the difference between the number and twice a natural number m.addCons(s == x - 2 * n) m.setObjective(s) m.optimize() assert m.getStatus() == "optimal" boolmod = m.getVal(s) == m.getVal(x) % 2 if verbose: for v in m.getVars(): print("%*s: %d" % (fmtlen, v, m.getVal(v))) print("%*d%%2 == %d?" % (fmtlen, m.getVal(x), m.getVal(s))) print("%*s" % (fmtlen, boolmod)) xval = m.getVal(x) sval = m.getVal(s) sstr = sdic[sval] print("%*d is %s" % (fmtlen, xval, sstr)) except (AssertionError, TypeError): print("%*s is neither even nor odd!" % (fmtlen, number.__repr__())) finally: if verbose: print(80 * "*") print("") return sval
Profit = {"Dry": 15, "Medium": 18, "Sweet": 30} Blends = Profit.keys() Use = { ("Alfrocheiro", "Dry"): 2, ("Alfrocheiro", "Medium"): 1, ("Alfrocheiro", "Sweet"): 1, ("Baga", "Dry"): 1, ("Baga", "Medium"): 2, ("Baga", "Sweet"): 1, ("Castelao", "Dry"): 0, ("Castelao", "Medium"): 0, ("Castelao", "Sweet"): 1 } # Create variables x = {} for j in Blends: x[j] = model.addVar(vtype="C", name="x(%s)" % j) # Create constraints c = {} for i in Grapes: c[i] = model.addCons(quicksum(Use[i, j] * x[j] for j in Blends) <= Inventory[i], name="Use(%s)" % i) # Objective model.setObjective(quicksum(Profit[j] * x[j] for j in Blends), "maximize") show_dual(model)
def scip_solver(graph, weight='weight'): try: from pyscipopt import Model, quicksum except ImportError: raise ImportError( 'SCIP Optimization Suit with Python support not found') nodes = graph.nodes() num_nodes = graph.number_of_nodes() c = nx.adjacency_matrix(graph, weight=weight) # Define the optimization problem model = Model('tsp') model.hideOutput() # silent/verbose mode # Create the variables x = {} for i in xrange(num_nodes): for j in xrange(i + 1, num_nodes): x[i, j] = model.addVar(ub=1, name='x(%s,%s)' % (i, j)) # Add the constraints for i in xrange(num_nodes): model.addCons( quicksum([x[j, i] for j in xrange(i)]) + quicksum([x[i, j] for j in xrange(i + 1, num_nodes)]) == 2, 'Degree(%s)' % i) # Set minimization objective model.setObjective( quicksum(c[i, j] * x[i, j] for i in xrange(num_nodes) for j in xrange(i + 1, num_nodes)), 'minimize') # Limit the number of edges in a connected component S to |S|-1 def addcut(cut_edges): G = nx.Graph() G.add_edges_from(cut_edges) Components = list(nx.connected_components(G)) if len(Components) == 1: return False model.freeTransform() for S in Components: model.addCons( quicksum(x[i, j] for i in S for j in S if j > i) <= len(S) - 1) return True # Solve EPS = 1.e-6 isMIP = False while True: model.optimize() edges = [] for (i, j) in x: if model.getVal(x[i, j]) > EPS: edges.append((i, j)) if addcut(edges) == False: if isMIP: # integer variables, components connected: solution found break model.freeTransform() for (i, j) in x: # all components connected, switch to integer model model.chgVarType(x[i, j], 'B') isMIP = True # Extract the tour from the edges G = nx.Graph() for e in edges: G.add_edge(nodes[e[0]], nodes[e[1]]) tour_edges = nx.eulerian_circuit(G, source=graph.nodes_iter().next()) tour = [e[0] for e in tour_edges] return tour
from pyscipopt import Model import numpy as np n = 10000 values = np.random.uniform(1, 5, n) weights = np.random.uniform(1, 5, n) capacity = np.sum(weights) * 0.2 model = Model() x = np.array([model.addVar(vtype="i") for i in range(n)]) model.setObjective(-np.sum(values * x)) model.addCons(np.sum(weights * x) <= capacity) for i in range(n): model.addCons(0 <= (x[i] <= 1)) model.optimize() # print("Items to take:") # for i in range(n): # print(f"\tItem {i:3}: {'*' if model.getVal(x[i]) > 0.5 else ' '}")
def transpt(L, L_tasks_mod, C, C_fictive, F, T, x_start, y_start, num_cities): """transp -- model for solving the transportation problem Parameters: L - dict of tasks with modified city numbers according to the layers and fictive flights, fighttime appended: {(o,d):[td, w, f_time]} L_tasks_mod - dict of tasks with modified city numbers according to the layers, fighttime appended: {(o,d):[td, w, f_time]} C - list of all cities over all layers plus fictive cities C_fictive - list of fictive cities F - dict of fleet {f:[w_max, tank_max]} T - set of discretized times x_start - dict of initial flights y_start - dict of initial ground postions Returns a model, ready to be solved. """ print('build optimisation problem...') model = Model("airfraight") # precision EPS = 1.e-6 # T_mod for ground arc variables T_mod = np.arange(-0.5, T[-1] + 1, 1) # --------------------------------------------------------------------------------------------------------- # Variables # Create variables x_fodt and y_ot x, y, z = {}, {}, {} print('building variables...') # decision variable x=1 if f flies from o to d with departure time t; x=0 else for f in F: for t in T: for o in C: for d in C: if o != d: x[f, o, d, t] = model.addVar(vtype="B", name="x(%s, %s, %s, %s)" % (f, o, d, t)) # ground arc variables (y=1 if aircraft f at location o at time t) for f in F: for t in T_mod: for o in C: y[f, o, t] = model.addVar(vtype="B", name="y(%s, %s, %s)" % (f, o, t)) # variable for tank at time t for an airplane f for f in F: for t in T: z[f, t] = model.addVar(vtype="C", name="z(%s, %s)" % (f, t)) # --------------------------------------------------------------------------------------------------------- # Constraints # (1) every task is flown exactly once for o in C: for d in C: if (o, d) in L_tasks_mod: model.addCons( quicksum(x[f, o, d, t] for f in F for t in T) == 1) # (2) continuity between flights and ground arches (very old version -> understand the calculation and does not work) for f in F: for t in T: for o in C: outgo_flight = quicksum(x[f, o, d, t] for d in C if (o, d) in L) income_flight = quicksum(x[f, d, o, t - L[d, o][2]] for d in C if (d, o) in L.keys() if t - L[d, o][2] >= 0) model.addCons(y[f, o, t - 0.5] + income_flight - outgo_flight - y[f, o, t + 0.5] == 0) # (3) assign the location of each aircraft in the beginning of optimisation if x_start != -1 and y_start != -1: # (3a) starting points for aircraft postition for k in y_start: model.addCons(y[k] == y_start[k]) # (3b) starting points for aircraft starting times at position to position for k in x_start: model.addCons(x[k] == x_start[k]) else: # (3c) starting from the base for f in F: model.addCons(y[f, C[0], T_mod[0]] == 1) C_mod = C[1:] for c in C_mod: model.addCons(y[f, c, T_mod[0]] == 0) # (6) no exceed of the capacity of the aircraft allowed for f in F: for t in T: for k, v in L_tasks_mod.items(): model.addCons(F[f][0] - v[1] * x[f, k[0], k[1], t] >= 0) # (7) no exceed of the deadline of the task for f in F: for t in T: for k, v in L_tasks_mod.items(): model.addCons(x[f, k[0], k[1], t] * t + v[2] <= v[0]) # (8) full tank at time 0 for f in F: model.addCons(z[f, 0] == F[f][1]) # (9) refill at base (C[0]) for f in F: for t in T: if t >= 1: C_without_base = [] for c in C_fictive: if t - L[c, C[0]][2] >= 0: C_without_base.append(c) C2_without_base = [] for o in C: for d in C: if (o, d) in L: if d != C[0] and t - L[o, d][2] >= 0: C2_without_base.append([o, d]) base_at_t = quicksum(x[f, o, C[0], t - L[o, C[0]][2]] for o in C_without_base) tank_loss = quicksum( (L[c[0], c[1]][2]) * x[f, c[0], c[1], t - L[c[0], c[1]][2]] for c in C2_without_base) # the "fuel" you have now, is the sum of all "fuel"-loss subtracted from the tank and filled by every # pass of the base model.addCons(z[f, t] == z[f, t - 1] - tank_loss + (-z[f, t - 1] + F[f][1]) * base_at_t) # at every time we need enough "fuel" in order to get back model.addCons(z[f, t] >= 0) # --------------------------------------------------------------------------------------------------------- # calculate cost dict{(f,o,d,t)} cost = dict() for f in range(len(F)): for t in T: for k, v in L.items(): if (k[0] % num_cities) == (k[1] % num_cities): cost[f, k[0], k[1], t] = 0.01 / len(L_tasks_mod) else: cost[f, k[0], k[1], t] = (F[f][0] - v[1]) * v[2] # Objective model.setObjective( quicksum(cost[f, o, d, t] * x[f, o, d, t] for f in F for o in C for d in C for t in T if (f, o, d, t) in cost), "minimize") print('solve optimisation problem...') model.optimize() model.data = x, y, z return model
def test_model(): # create solver instance s = Model() # test parameter methods pric = s.getParam('lp/pricing') s.setParam('lp/pricing', 'q') assert 'q' == s.getParam('lp/pricing') s.setParam('lp/pricing', pric) s.setParam('visual/vbcfilename', 'vbcfile') assert 'vbcfile' == s.getParam('visual/vbcfilename') assert 'lp/pricing' in s.getParams() s.setParams({'visual/vbcfilename': '-'}) assert '-' == s.getParam('visual/vbcfilename') # add some variables x = s.addVar("x", vtype='C', obj=1.0) y = s.addVar("y", vtype='C', obj=2.0) assert x.getObj() == 1.0 assert y.getObj() == 2.0 s.setObjective(4.0 * y + 10.5, clear=False) assert x.getObj() == 1.0 assert y.getObj() == 4.0 assert s.getObjoffset() == 10.5 # add some constraint c = s.addCons(x + 2 * y >= 1.0) assert c.isLinear() s.chgLhs(c, 5.0) s.chgRhs(c, 6.0) assert s.getLhs(c) == 5.0 assert s.getRhs(c) == 6.0 # solve problem s.optimize() solution = s.getBestSol() # print solution assert (s.getVal(x) == s.getSolVal(solution, x)) assert (s.getVal(y) == s.getSolVal(solution, y)) assert round(s.getVal(x)) == 5.0 assert round(s.getVal(y)) == 0.0 assert s.getSlack(c, solution) == 0.0 assert s.getSlack(c, solution, 'lhs') == 0.0 assert s.getSlack(c, solution, 'rhs') == 1.0 assert s.getActivity(c, solution) == 5.0 # check expression evaluations expr = x * x + 2 * x * y + y * y expr2 = x + 1 assert s.getVal(expr) == s.getSolVal(solution, expr) assert s.getVal(expr2) == s.getSolVal(solution, expr2) assert round(s.getVal(expr)) == 25.0 assert round(s.getVal(expr2)) == 6.0 s.writeProblem('model') s.writeProblem('model.lp') s.freeProb() s = Model() x = s.addVar("x", vtype='C', obj=1.0) y = s.addVar("y", vtype='C', obj=2.0) c = s.addCons(x + 2 * y <= 1.0) s.setMaximize() s.delCons(c) s.optimize() assert s.getStatus() == 'unbounded'
def solve(epitopes): """ Map each vertex to the set of incoming edge variables. """ incoming_edges = collections.defaultdict(list) outgoing_edges = collections.defaultdict(list) source_edges = [] sink_edges = [] model = Model() print('got the model') print('size of epitopes: ' + str(len(epitopes))) for u, u_count in epitopes.items(): #add incoming edge from source node variable = model.addVar(vtype='B') incoming_edges[u].append((variable, u)) source_edges.append((u, variable)) #add outgoing edge to sink node variable = model.addVar(vtype='B') outgoing_edges[u].append((variable, None)) sink_edges.append(variable) for v, v_count in epitopes.items(): if (not u == v) and u[1::] == v[0:-1]: #add a variable for the edge. variable = model.addVar(vtype='B', lb=0, ub=1) incoming_edges[v].append((variable, u)) outgoing_edges[u].append((variable, v)) print('added variables') for u, u_count in epitopes.items(): #for each vertex, make sure at most one incoming edge is part of the path model.addCons(quicksum([x[0] for x in incoming_edges[u]]) <= 1) #balance the outgoing and incoming edges for each node model.addCons(quicksum([x[0] for x in incoming_edges[u]]) == quicksum([x[0] for x in outgoing_edges[u]])) #exactly one edge coming out of the source is part of the path. model.addCons(quicksum([x[1] for x in source_edges]) == 1) #exactly one edge going into the sink is part of the path model.addCons(quicksum(sink_edges) == 1) print('added constraints') #now, formulate the objective function. model.setObjective(quicksum([u_count*quicksum([x[0] for x in incoming_edges[u]]) for u,u_count in epitopes.items()]), 'maximize') print('set objective') model.optimize() starting_vertex = None for source_edge in source_edges: #sometimes it's slightly off by a tiny bit (like 10^-12 or something) if round(model.getVal(source_edge[1])) == 1: starting_vertex = source_edge[0] break assert(starting_vertex) path = [starting_vertex] while True: edges = outgoing_edges[starting_vertex] variable = None next_vertex = None for var, seq in edges: if round(model.getVal(var)) == 1: variable = var next_vertex = seq break if next_vertex: path.append(next_vertex) starting_vertex = next_vertex else: print('breaking') break assert(len(path) == len(set(path))) synthetic = path[0] + ''.join(x[-1] for x in path[1::]) return synthetic
def solveCuttingStock(w, q, B): """solveCuttingStock: use column generation (Gilmore-Gomory approach). Parameters: - w: list of item's widths - q: number of items of a width - B: bin/roll capacity Returns a solution: list of lists, each of which with the cuts of a roll. """ t = [] # patterns m = len(w) # Generate initial patterns with one size for each item width for (i, width) in enumerate(w): pat = [ 0 ] * m # vector of number of orders to be packed into one roll (bin) pat[i] = int(B / width) t.append(pat) # if LOG: # print "sizes of orders=",w # print "quantities of orders=",q # print "roll size=",B # print "initial patterns",t K = len(t) master = Model("master LP") # master LP problem x = {} for k in range(K): x[k] = master.addVar(vtype="I", name="x(%s)" % k) orders = {} for i in range(m): orders[i] = master.addCons( quicksum(t[k][i] * x[k] for k in range(K) if t[k][i] > 0) >= q[i], "Order(%s)" % i) master.setObjective(quicksum(x[k] for k in range(K)), "minimize") # master.Params.OutputFlag = 0 # silent mode # iter = 0 while True: # print "current patterns:" # for ti in t: # print ti # print # iter += 1 relax = master.relax() relax.optimize() pi = [relax.getDualsolLinear(c) for c in relax.getConss()] # keep dual variables knapsack = Model("KP") # knapsack sub-problem knapsack.setMaximize # maximize y = {} for i in range(m): y[i] = knapsack.addVar(lb=0, ub=q[i], vtype="I", name="y(%s)" % i) knapsack.addCons(quicksum(w[i] * y[i] for i in range(m)) <= B, "Width") knapsack.setObjective(quicksum(pi[i] * y[i] for i in range(m)), "maximize") knapsack.hideOutput() # silent mode knapsack.optimize() # if LOG: # print "objective of knapsack problem:", knapsack.ObjVal if knapsack.getObjVal() < 1 + EPS: # break if no more columns break pat = [int(y[i].X + 0.5) for i in y] # new pattern t.append(pat) # if LOG: # print "shadow prices and new pattern:" # for (i,d) in enumerate(pi): # print "\t%5s%12s%7s" % (i,d,pat[i]) # print # add new column to the master problem col = Column() for i in range(m): if t[K][i] > 0: col.addTerms(t[K][i], orders[i]) x[K] = master.addVar(obj=1, vtype="I", name="x(%s)" % K, column=col) # master.write("MP" + str(iter) + ".lp") K += 1 # Finally, solve the IP # if LOG: # master.Params.OutputFlag = 1 # verbose mode master.optimize() # if LOG: # print # print "final solution (integer master problem): objective =", master.ObjVal # print "patterns:" # for k in x: # if x[k].X > EPS: # print "pattern",k, # print "\tsizes:", # print [w[i] for i in range(m) if t[k][i]>0 for j in range(t[k][i]) ], # print "--> %s rolls" % int(x[k].X+.5) rolls = [] for k in x: for j in range(int(x[k].X + .5)): rolls.append( sorted([ w[i] for i in range(m) if t[k][i] > 0 for j in range(t[k][i]) ])) rolls.sort() return rolls
def assignment02(SCENARIO1Revenue, SCENARIO2Revenue, SCENARIO3Revenue, SCENARIO1Yield, SCENARIO2Yield, SCENARIO3Yield, Varieties, WineBrand, Percentage, Costs, Areas, Parcels, BigM, Scenarios): model = Model("assignment02") ################### # -- Variables -- # ################### x, y, z, a, t, g = {}, {}, {}, {}, {}, {} # x - amount of barels of vareity v used in wine w in scenario s # y - planted area of variety v in parcel p # t - "fake" varible that counts the produced quantity of varity v in scenario s # g - "fake" varible that counts the produced quantity of wine w in scenario s # a - binary variable that turns into 1 when we produce more than 5 barels of a wine brand in scenario s # z - binary variable that turns into 1 when we produce variety v in parcel p for v in Varieties: for w in WineBrand: for s in Scenarios: x[v, w, s] = model.addVar(vtype="C", name="x(%s,%s,%s)" % (v, w, s)) for v in Varieties: for p in Parcels: z[v, p] = model.addVar(vtype="B", name="z(%s,%s)" % (v, p)) y[v, p] = model.addVar(vtype="C", name="y(%s,%s)" % (v, p)) for w in WineBrand: for s in Scenarios: a[w, s] = model.addVar(vtype="B", name="a(%s,%s)" % (w, s)) for v in Varieties: for s in Scenarios: t[v, s] = model.addVar(vtype="C", name="t(%s,%s)" % (v, s)) for w in WineBrand: for s in Scenarios: g[w, s] = model.addVar(vtype="C", name="g(%s,%s)" % (w, s)) ###################### # -- Restrictions -- # ###################### for v in Varieties: model.addCons(t[v, 1] == quicksum(SCENARIO1Yield[v][p] * y[v, p] for p in Parcels)) model.addCons(t[v, 2] == quicksum(SCENARIO2Yield[v][p] * y[v, p] for p in Parcels)) model.addCons(t[v, 3] == quicksum(SCENARIO3Yield[v][p] * y[v, p] for p in Parcels)) for s in Scenarios: for w in WineBrand: model.addCons(g[w, s] == quicksum(x[v, w, s] for v in Varieties)) for v in Varieties: for p in Parcels: model.addCons(y[v, p] <= BigM * z[v, p], "Area Big M") model.addCons(quicksum(y[v, p] * Costs[v] + FIXED_COST * z[v, p] for v in Varieties for p in Parcels) <= B, "Budget") for p in Parcels: model.addCons(quicksum(y[v, p] for v in Varieties) <= Areas[p], "Maximum Area") for v in Varieties: for s in Scenarios: model.addCons(quicksum(x[v, w, s] for w in WineBrand) <= t[v, s], "Can't use more than what was produced") for v in Varieties: for w in WineBrand: for s in Scenarios: model.addCons(x[v, w, s] >= g[w, s] * Percentage[v][w], "Minimum Percentage") for w in WineBrand: for s in Scenarios: model.addCons(quicksum(x[v, w, s] for v in Varieties) >= 5 * a[w, s], "More than five Barrels") for s in Scenarios: model.addCons(quicksum(a[w, s] for w in WineBrand) >= 3, "At least three Brands") ################### # -- Objective -- # ################### ratio = 1 / 3 model.setObjective((quicksum(g[w, 1] * SCENARIO1Revenue[w] * ratio for w in WineBrand) + quicksum(g[w, 2] * SCENARIO2Revenue[w] * ratio for w in WineBrand) + quicksum(g[w, 3] * SCENARIO3Revenue[w] * ratio for w in WineBrand)), "maximize") model.data = x, y, z, a, t, g return model
def scheduling_cutting_plane(J,p,r,w): """ scheduling_cutting_plane: heuristic to one machine weighted completion time based on cutting planes Use a cutting-plane method as a heuristics for solving the one-machine total weighted completion time problem with release times. Parameters: - J: set of jobs - p[j]: processing time of job j - r[j]: earliest start time of job j - w[j]: weighted of job j; the objective is the sum of the weighted completion time Returns a tuple with values of: - bestC: corresponding completion time of the best found solution - bestobj: best, best, hobj """ model = Model("scheduling: cutting plane") C = {} # completion time variable for j in J: C[j] = model.addVar(lb=r[j]+p[j], obj=w[j], vtype="C", name="C(%s)"%j) sumP = sum([p[j] for j in J]) sumP2 = sum([p[j]**2 for j in J]) model.addCons(C[j]*p[j] >= sumP2*0.5 + (sumP**2)*0.5, "AllJobs") model.setObjective(quicksum(w[j]*C[j] for j in J), "minimize") cut = 0 bestobj = float("inf") while True: model.optimize() sol = sorted([(model.getVal(C[j]),j) for j in C]) seq = [j for (completion,j) in sol] # print("Opt.value=",model.getObjVal() # print("current solution:", seq hC,hobj = evaluate(seq,p,r,w) if hobj < bestobj: # print("\t*** updating best found solution:", bestobj, "--->", hobj, "***" bestC = hC bestobj = hobj best = list(seq) S,S_ = [],[] sumP,sumP2,f = 0,0,0 for (C_,j) in sol: pj = p[j] delta = pj**2 + ((sumP+pj)**2 - sumP**2) - 2*pj*C_ if f > 0 and delta <= 0: S = S_ break f += delta/2. sumP2 += pj**2 sumP += pj S_.append(j) if S == []: break cut += 1 model.addCons(quicksum(C[j]*p[j] for j in S) >= sumP2*0.5 + (sumP**2)*0.5, "Cut(%s)"%cut) return bestC,bestobj,best
# @file tutorial/puzzle.py # @brief solve a simple puzzle using SCIP """ On a beach there are octopuses, turtles and cranes. The total number of legs of all animals is 80, while the number of heads is 32. What are the minimum numbers of turtles and octopuses, respectively? Copyright (c) by Joao Pedro PEDROSO and Mikio KUBO, 2012 """ from pyscipopt import Model model = Model("puzzle", enablepricing=False) x = model.addVar(vtype="I", name="octopusses") #, pricedVar=True) y = model.addVar(vtype="I", name="turtles") z = model.addVar(vtype="I", name="cranes") # Set up constraint for number of heads model.addCons(x + y + z == 32, name="Heads") # Set up constraint for number of legs model.addCons(8 * x + 4 * y + 2 * z == 80, name="Legs") # TODO infeasible, but answers cons1 = model.addCons(x <= 1, initial=False, modifiable=True, removable=True) cons2 = model.addCons(y <= 3) # Set objective function model.setObjective(x + y, "minimize") # model.hideOutput() # model.writeStatistics('/tmp/stat.out') model.writeLP('./Lp.lp')
def test_gastrans(): GASTEMP = 281.15 RUGOSITY = 0.05 DENSITY = 0.616 COMPRESSIBILITY = 0.8 nodes = [ # name supplylo supplyup pressurelo pressureup cost ("Anderlues", 0.0, 1.2, 0.0, 66.2, 0.0), # 0 ("Antwerpen", None, -4.034, 30.0, 80.0, 0.0), # 1 ("Arlon", None, -0.222, 0.0, 66.2, 0.0), # 2 ("Berneau", 0.0, 0.0, 0.0, 66.2, 0.0), # 3 ("Blaregnies", None, -15.616, 50.0, 66.2, 0.0), # 4 ("Brugge", None, -3.918, 30.0, 80.0, 0.0), # 5 ("Dudzele", 0.0, 8.4, 0.0, 77.0, 2.28), # 6 ("Gent", None, -5.256, 30.0, 80.0, 0.0), # 7 ("Liege", None, -6.385, 30.0, 66.2, 0.0), # 8 ("Loenhout", 0.0, 4.8, 0.0, 77.0, 2.28), # 9 ("Mons", None, -6.848, 0.0, 66.2, 0.0), # 10 ("Namur", None, -2.120, 0.0, 66.2, 0.0), # 11 ("Petange", None, -1.919, 25.0, 66.2, 0.0), # 12 ("Peronnes", 0.0, 0.96, 0.0, 66.2, 1.68), # 13 ("Sinsin", 0.0, 0.0, 0.0, 63.0, 0.0), # 14 ("Voeren", 20.344, 22.012, 50.0, 66.2, 1.68), # 15 ("Wanze", 0.0, 0.0, 0.0, 66.2, 0.0), # 16 ("Warnand", 0.0, 0.0, 0.0, 66.2, 0.0), # 17 ("Zeebrugge", 8.87, 11.594, 0.0, 77.0, 2.28), # 18 ("Zomergem", 0.0, 0.0, 0.0, 80.0, 0.0) # 19 ] arcs = [ # node1 node2 diameter length active */ (18, 6, 890.0, 4.0, False), (18, 6, 890.0, 4.0, False), (6, 5, 890.0, 6.0, False), (6, 5, 890.0, 6.0, False), (5, 19, 890.0, 26.0, False), (9, 1, 590.1, 43.0, False), (1, 7, 590.1, 29.0, False), (7, 19, 590.1, 19.0, False), (19, 13, 890.0, 55.0, False), (15, 3, 890.0, 5.0, True), (15, 3, 395.0, 5.0, True), (3, 8, 890.0, 20.0, False), (3, 8, 395.0, 20.0, False), (8, 17, 890.0, 25.0, False), (8, 17, 395.0, 25.0, False), (17, 11, 890.0, 42.0, False), (11, 0, 890.0, 40.0, False), (0, 13, 890.0, 5.0, False), (13, 10, 890.0, 10.0, False), (10, 4, 890.0, 25.0, False), (17, 16, 395.5, 10.5, False), (16, 14, 315.5, 26.0, True), (14, 2, 315.5, 98.0, False), (2, 12, 315.5, 6.0, False) ] scip = Model() # create flow variables flow = {} for arc in arcs: flow[arc] = scip.addVar( "flow_%s_%s" % (nodes[arc[0]][0], nodes[arc[1]][0]), # names of nodes in arc lb=0.0 if arc[4] else None) # no lower bound if not active # pressure difference variables pressurediff = {} for arc in arcs: pressurediff[arc] = scip.addVar( "pressurediff_%s_%s" % (nodes[arc[0]][0], nodes[arc[1]][0]), # names of nodes in arc lb=None) # supply variables supply = {} for node in nodes: supply[node] = scip.addVar("supply_%s" % (node[0]), lb=node[1], ub=node[2], obj=node[5]) # square pressure variables pressure = {} for node in nodes: pressure[node] = scip.addVar("pressure_%s" % (node[0]), lb=node[3]**2, ub=node[4]**2) # node balance constrains, for each node i: outflows - inflows = supply for nid, node in enumerate(nodes): # find arcs that go or end at this node flowbalance = 0 for arc in arcs: if arc[0] == nid: # arc is outgoing flowbalance += flow[arc] elif arc[1] == nid: # arc is incoming flowbalance -= flow[arc] else: continue scip.addCons(flowbalance == supply[node], name="flowbalance%s" % node[0]) # pressure difference constraints: pressurediff[node1 to node2] = pressure[node1] - pressure[node2] for arc in arcs: scip.addCons( pressurediff[arc] == pressure[nodes[arc[0]]] - pressure[nodes[arc[1]]], "pressurediffcons_%s_%s" % (nodes[arc[0]][0], nodes[arc[1]][0])) # pressure loss constraints: # active arc: flow[arc]^2 + coef * pressurediff[arc] <= 0.0 # regular pipes: flow[arc] * abs(flow[arc]) - coef * pressurediff[arc] == 0.0 # coef = 96.074830e-15*diameter(i)^5/(lambda*compressibility*temperatur*length(i)*density) # lambda = (2*log10(3.7*diameter(i)/rugosity))^(-2) from math import log10 for arc in arcs: coef = 96.074830e-15 * arc[2]**5 * ( 2.0 * log10(3.7 * arc[2] / RUGOSITY) )**2 / COMPRESSIBILITY / GASTEMP / arc[3] / DENSITY if arc[4]: # active scip.addCons( flow[arc]**2 + coef * pressurediff[arc] <= 0.0, "pressureloss_%s_%s" % (nodes[arc[0]][0], nodes[arc[1]][0])) else: scip.addCons( flow[arc] * abs(flow[arc]) - coef * pressurediff[arc] == 0.0, "pressureloss_%s_%s" % (nodes[arc[0]][0], nodes[arc[1]][0])) scip.setRealParam('limits/time', 5) scip.optimize() if scip.getStatus() == 'timelimit': pytest.skip() assert abs(scip.getPrimalbound() - 89.08584) < 1.0e-5