Commit 9568428e authored by msurl's avatar msurl
Browse files

added object oriented approach including inheritance

parent d0d71e83
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon May 18 18:44:09 2020
@author: mario
"""
import networkx as nx
import gurobipy as gp
from gurobipy import GRB
import datetime
import sys
import matplotlib.pyplot as plt
# import lp_to_nx_graph
class DominatingSet:
def __init__(self, G, name = "DS"):
self.G = G
self.m = gp.Model(name)
self.nodes = self.m.addVars(G.nodes, vtype = GRB.BINARY, name = "nodes")
self.m.setObjective(gp.quicksum(self.nodes), GRB.MINIMIZE)
# For each node in the graph the node itself or at least one of it's neighbors has to be part of the dominating set
self.m.addConstrs(((gp.quicksum(self.nodes[n] for n in G.neighbors(v)) + self.nodes[v] )>= 1) for v in G.nodes)
def solve(self):
ds = {i for i,x_i in enumerate(self.m.getVars()) if x_i.x == 1}
return ds
def solve_and_draw(self):
starttime = datetime.datetime.now()
ds = self.solve()
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"duration in seconds: {duration_sec}")
nx.draw_kamada_kawai(self.G, node_color = color_map, with_labels = True)
plt.show()
class KHopDominatingSet(DominatingSet):
def __init__(self, G, k, name = "kDS"):
super().__init__(KHopDominatingSet.make_closure(G,k), name)
self.G = G
def make_closure(G, k):
G_prime = nx.Graph(G)
for v in G.nodes:
neighbors = set(G.neighbors(v))
for i in range(k-1):
neighbors.update([w for n in neighbors for w in G.neighbors(n)])
G_prime.add_edges_from((v,n) for n in neighbors)
return G_prime
class ConnectedKHopDominatingSet(KHopDominatingSet):
def __init__(self, G, k, name = "CkDS"):
self.G = G
super().__init__(G, k, name)
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)
C_i_prime = C_i.copy()
C_i_prime.update(N_ci)
G_prime.remove_edges_from(G.subgraph(C_i_prime).edges)
# dijkstra
R_j = nx.algorithms.dag.descendants(G_prime, j)
return R_j.intersection(N_ci)
def solve(self):
return self.solve_iteratively(float("inf"))
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 == 1}
G_prime_prime = self.G.subgraph(ds)
while(not nx.is_connected(G_prime_prime)) and iterations < maxIterations:
iterations+=1
C = [c for c in nx.algorithms.components.connected_components(G_prime_prime)]
for i in range(len(C)-1):
C_i = C[i]
for j in range(i+1, len(C)):
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)
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)
self.root = root
self.m.addConstr(self.nodes[root] >= 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")
# dsProb = RootedConnectecKHopDominatingSet(G, k, 0)
# dsProb.solve_and_draw()
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed May 13 17:03:41 2020
@author: mario
"""
import networkx as nx
import re
# def lp_to_nx_graph(strInput):
# nodePattern = re.compile(r'node\([0-9]+\.\.[0-9]+\)\.')
# print(nodePattern.findall("node(0..195)."))
# lp_to_nx_graph("")
def cleanLP(lpSTR):
lpSTR = lpSTR.replace(" ", "")
lpSTR = lpSTR.replace("\t", "")
newLPList = []
for line in lpSTR.split("\n"):
toAdd = line
if "%" in line:
toAdd = line[:line.index("%")]
if toAdd != "":
newLPList.append(toAdd)
return newLPList
def lpStrToGraphNX(lpSTR):
lpList = cleanLP(lpSTR)
graph = nx.empty_graph(0)
for part in lpList:
if ".." in part and "node" in part:
startrange = int(part[5:part.index("..")])
endrange = int(part[part.index("..")+2:part.index(").")])
graph.add_nodes_from(range(startrange, endrange))
elif "." in part and ".." not in part:
for i in part.split("."):
if "node(" in i:
graph.add_node(int(i[5:-1]))
elif "edge(" in i:
first = int(i[5:i.index(",")])
second = int(i[i.index(",")+1:-1])
graph.add_edge(first, second)
if(first == 13 or first == 9):
if(second == 13 or second == 9):
print("Hello")
return graph
def read(filenameRaw):
fileIn = open(filenameRaw,'r')
graph = lpStrToGraphNX(fileIn.read())
return graph
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment