Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
from pyscipopt import Model, Conshdlr, quicksum, SCIP_RESULT
import pytest
itertools = pytest.importorskip("itertools")
networkx = pytest.importorskip("networkx")
EPS = 1.e-6
# subtour elimination constraint handler
class TSPconshdlr(Conshdlr):
def __init__(self, variables):
self.variables = variables
# find subtours in the graph induced by the edges {i,j} for which x[i,j] is positive
# at the given solution; when solution is None, then the LP solution is used
def find_subtours(self, solution = None):
edges = []
x = self.variables
for (i, j) in x:
if self.model.getSolVal(solution, x[i, j]) > EPS:
edges.append((i, j))
G = networkx.Graph()
G.add_edges_from(edges)
components = list(networkx.connected_components(G))
entering()
print("I HOPE I DON'T HAVE TO IMPLEMENT THIS GUY!!!")
raise ValueError("Don't be lazy; implement me!")
leaving()
########### END BRANCHING
############ THE CONSHDLR FOR STOREGRAPH CONSTRAINTS
def getCurrentGraph(scip):
conshdlr = scip.conshdlr #this is the equivalent of scipfindconshdlr
assert len(conshdlr.stack) > 0
graph = conshdlr.stack[-1].data["current_graph"]
assert graph != None
return graph
class StoreGraphConshdlr(Conshdlr):
def __init__(self): # here comes the conshdlr data
entering()
self.stack = []
leaving()
# we do it this way in name of efficieny :) we could just create the graph right away and
# wouldn't have to bother storing the parent's graph (we need node1 and node2, see prop)
def createCons(self, name, node1, node2, parent_graph, type, stickingnode):
entering()
cons = self.model.createCons(self, name, stickingatnode=True)
cons.data = {} # FIXME: I think I don't like this. For no other object we use the `data` field...
cons.data["node1"] = node1
cons.data["node2"] = node2
cons.data["parent_graph"] = parent_graph
cons.data["type"] = type
cons.data["stickingatnode"] = stickingnode
# consenfops
# consresprop
# conscopy
# consparse
# consgetvars
# consgetdivebdchgs
## callbacks which are not called are:
# conssepasol
# consdelvars
# consprint
ids = []
calls = set([])
class MyConshdlr(Conshdlr):
def __init__(self, shouldtrans, shouldcopy):
self.shouldtrans = shouldtrans
self.shouldcopy = shouldcopy
def createData(self, constraint, nvars, othername):
print("Creating data for my constraint: %s"%constraint.name)
constraint.data = SimpleNamespace()
constraint.data.nvars = nvars
constraint.data.myothername = othername
## fundamental callbacks ##
def consenfolp(self, constraints, nusefulconss, solinfeasible):
calls.add("consenfolp")
for constraint in constraints:
assert id(constraint) in ids
X,Y = networkx.bipartite.sets(G)
pos = dict()
pos.update( (n, (1, i)) for i, n in enumerate(X) ) # put nodes from X at x=1
pos.update( (n, (2, i)) for i, n in enumerate(Y) ) # put nodes from Y at x=2
networkx.draw(G, pos=pos, with_labels=False)
labels = {}
for node in G.nodes():
labels[node] = node
networkx.draw_networkx_labels(G, pos, labels)
plt.show()
# all different constraint handler
class ALLDIFFconshdlr(Conshdlr):
# value graph: bipartite graph between variables and the union of their domains
# an edge connects a variable and a value iff the value is in the variable's domain
def build_value_graph(self, vars, domains):
#print(domains)
vals = set([])
for var in vars:
#print("domain of var ", var.name, "is ", domains[var])
vals.update(domains[var.ptr()]) # vals = vals union domains[var]
G = networkx.Graph()
G.add_nodes_from((var.name for var in vars), bipartite = 0) # add vars names as nodes
G.add_nodes_from(vals, bipartite = 1) # add union of values as nodes
for var in vars:
for value in domains[var.ptr()]:
"""
tsp.py: solve the traveling salesman problem
minimize the travel cost for visiting n customers exactly once
approach:
- start with assignment model
- add cuts until there are no sub-cycles
Copyright (c) by Joao Pedro PEDROSO and Mikio KUBO, 2012
"""
import math
import random
import networkx
from pyscipopt import Model, Conshdlr, quicksum, SCIP_RESULT, SCIP_PRESOLTIMING, SCIP_PROPTIMING, SCIP_PARAMSETTING
class TSPconshdlr(Conshdlr):
def findSubtours(self, checkonly, sol):
EPS = 1.e-6
edges = []
x = self.model.data
for (i, j) in x:
if self.model.getSolVal(sol, x[i, j]) > EPS:
edges.append((i,j))
G = networkx.Graph()
G.add_edges_from(edges)
Components = list(networkx.connected_components(G))
if len(Components) == 1:
return False
elif checkonly:
"""
lotsizing_lazy.py: solve the single-item lot-sizing problem.
Approaches:
- sils: solve the problem using the standard formulation
- sils_cut: solve the problem using cutting planes
Copyright (c) by Joao Pedro PEDROSO and Mikio KUBO, 2012
"""
from pyscipopt import Model, Conshdlr, quicksum, multidict, SCIP_RESULT, SCIP_PRESOLTIMING, SCIP_PROPTIMING
class Conshdlr_sils(Conshdlr):
def addcut(self, checkonly, sol):
D,Ts = self.data
y,x,I = self.model.data
cutsadded = False
for ell in Ts:
lhs = 0
S,L = [],[]
for t in range(1,ell+1):
yt = self.model.getSolVal(sol, y[t])
xt = self.model.getSolVal(sol, x[t])
if D[t,ell]*yt < xt:
S.append(t)
lhs += D[t,ell]*yt
else:
"""
vrp.py: model for the vehicle routing problem using callback for adding cuts.
approach:
- start with assignment model
- add cuts until all components of the graph are connected
Copyright (c) by Joao Pedro PEDROSO and Mikio KUBO, 2012
"""
import math
import random
import networkx
from pyscipopt import Model, Conshdlr, quicksum, multidict, SCIP_RESULT, SCIP_PRESOLTIMING, SCIP_PROPTIMING
class VRPconshdlr(Conshdlr):
def addCuts(self, checkonly):
"""add cuts if necessary and return whether model is feasible"""
cutsadded = False
edges = []
x = self.model.data
for (i, j) in x:
if self.model.getVal(x[i, j]) > .5:
if i != V[0] and j != V[0]:
edges.append((i, j))
G = networkx.Graph()
G.add_edges_from(edges)
Components = list(networkx.connected_components(G))
for S in Components:
S_card = len(S)
q_sum = sum(q[i] for i in S)