Skip to content
Snippets Groups Projects
Commit 1b55a361 authored by msurl's avatar msurl
Browse files

added callback function for gurobi to lazily add connectivity constraints and refactored code

parent f1dd6676
Branches
No related tags found
No related merge requests found
......@@ -11,7 +11,7 @@ from gurobipy import GRB
import datetime
import sys
import matplotlib.pyplot as plt
# import lp_to_nx_graph
import lp_to_nx_graph
class DominatingSet:
......@@ -60,12 +60,20 @@ class KHopDominatingSet(DominatingSet):
class ConnectedKHopDominatingSet(KHopDominatingSet):
def __init__(self, G, k, name = "CkDS"):
def __init__(self, G, k, name = "CkDS", exclude = {}):
self.G = G
super().__init__(G, k, name)
# self.m.addConstr(gp.quicksum(gp.quicksum(self.nodes[w] for w in G.neighbors(v)) -2*self.nodes[v] for v in G.nodes) >= -2)
if exclude:
self.m.addConstrs(self.nodes[v] <= gp.quicksum(self.nodes[w] for w in G.neighbors(v)) for v in G.nodes if v not in exclude)
else:
self.m.addConstrs(self.nodes[v] <= gp.quicksum(self.nodes[w] for w in G.neighbors(v)) for v in G.nodes)
def min_ij_separator(G, i, j, C_i):
N_ci = {v for c in C_i for v in G.neighbors(c)}
G_prime = nx.Graph(G)
......@@ -77,17 +85,21 @@ class ConnectedKHopDominatingSet(KHopDominatingSet):
return R_j.intersection(N_ci)
def solve(self):
return self.solve_iteratively(float("inf"))
self.m._vars = self.nodes
self.m._G = self.G
self.m.Params.lazyConstraints = 1
self.m.optimize(RootedConnectecKHopDominatingSet.elim_unconnectivity)
def solve_iteratively(self, maxIterations):
iterations = 0
self.m.optimize()
ds = {i for i,x_i in enumerate(self.m.getVars()) if x_i.x > 0.5}
return ds
ds = {i for i,x_i in enumerate(self.m.getVars()) if x_i.x == 1}
def elim_unconnectivity(model, where):
if where == GRB.Callback.MIPSOL:
vals = model.cbGetSolution(model._vars)
ds = {i for i in model._vars.keys() if vals[i] > 0.5}
G_prime_prime = self.G.subgraph(ds)
while(not nx.is_connected(G_prime_prime)) and iterations < maxIterations:
iterations+=1
G_prime_prime = model._G.subgraph(ds)
if(not nx.is_connected(G_prime_prime)):
C = [c for c in nx.algorithms.components.connected_components(G_prime_prime)]
for i in range(len(C)-1):
C_i = C[i]
......@@ -95,46 +107,26 @@ class ConnectedKHopDominatingSet(KHopDominatingSet):
C_j = C[j]
h = next(iter(C_i))
l = next(iter(C_j))
min_ij_sep = ConnectedKHopDominatingSet.min_ij_separator(self.G, h, l, C_i)
self.m.addConstr(gp.quicksum(self.nodes[s] for s in min_ij_sep) >= self.nodes[h] + self.nodes[l] - 1)
self.m.optimize()
ds = {i for i,x_i in enumerate(self.m.getVars()) if x_i.x == 1}
G_prime_prime = self.G.subgraph(ds)
min_ij_sep = ConnectedKHopDominatingSet.min_ij_separator(model._G, h, l, C_i)
model.cbLazy(gp.quicksum(model._vars[s] for s in min_ij_sep) >= model._vars[h] + model._vars[l] - 1)
return ds, iterations
def solve_and_draw(self, iterations = float("inf")):
starttime = datetime.datetime.now()
ds, iterations = self.solve_iteratively(iterations)
endtime = datetime.datetime.now()
duration = endtime- starttime
duration_sec = duration.total_seconds()
color_map = ['red' if i in ds else 'green' for i in self.G.nodes]
print(f"iterations: {iterations}, duration in seconds: {duration_sec}")
nx.draw_kamada_kawai(self.G, node_color = color_map, with_labels = True)
plt.show()
class RootedConnectecKHopDominatingSet(ConnectedKHopDominatingSet):
def __init__(self, G, k, root = 0, name = "RCkDS"):
super().__init__(G, k, name)
super().__init__(G, k, name, exclude = {root})
self.root = root
self.m.addConstr(self.nodes[root] >= 1)
# if __name__ == '__main__':
# G = lp_to_nx_graph.read(sys.argv[1])
if __name__ == '__main__':
G = lp_to_nx_graph.read(sys.argv[1])
# if(len(sys.argv) > 2):
# k = int(sys.argv[2])
# else:
# k = 1
# if(len(sys.argv) > 3):
# maxIterations = int(sys.argv[3])
# else:
# maxIterations = float("inf")
if(len(sys.argv) > 2):
k = int(sys.argv[2])
else:
k = 1
# dsProb = RootedConnectecKHopDominatingSet(G, k, 0)
# dsProb.solve_and_draw()
dsProb = RootedConnectecKHopDominatingSet(G, k, 0)
dsProb.solve_and_draw()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment