| import numpy as np |
| from word_definite import * |
| import math |
|
|
| def Parent(i): |
| return max(0, math.floor((i - 1)/2)) |
|
|
| def Left(i): |
| return 2*i + 1 |
|
|
| def Right(i): |
| return 2*(i + 1) |
|
|
|
|
| """ |
| ################################################################################################ |
| ######################## NOMINAL NODE CLASS REQUIRED FOR USING ################################ |
| ######################### WITH THE HEAP DATA STRUCTURE ####################################### |
| ################################################################################################ |
| """ |
|
|
| class Node: |
| def __init__(self, id, dist): |
| self.dist = dist |
| self.id = id |
| self.isConflicted = False |
| self.src = -1 |
|
|
| """ |
| ################################################################################################ |
| ############################ IMPLEMENTATION OF HEAP ########################################## |
| ################################################################################################ |
| """ |
|
|
| class Heap: |
| |
| |
| def __init__(self, nodeList): |
| self.nodeList = [n for n in nodeList] |
| self.len = len(nodeList) |
| self.idLocator = {} |
| for i in range(self.len): |
| self.idLocator[nodeList[i].id] = i |
| self.Build() |
| |
| def Exchange(self, i, j): |
| t = self.nodeList[i] |
| self.nodeList[i] = self.nodeList[j] |
| self.nodeList[j] = t |
| self.idLocator[self.nodeList[i].id] = i |
| self.idLocator[self.nodeList[j].id] = j |
| |
| def Decrease_Key(self, node, newDist, src): |
| if node.isConflicted: |
| return |
| i = self.idLocator[node.id] |
| if newDist > node.dist: |
| |
| return |
| else: |
| node.dist = newDist |
| node.src = src |
| parent = Parent(i) |
| while ((i > 0) and (self.nodeList[parent].dist > self.nodeList[i].dist)): |
| self.Exchange(i, parent) |
| i = parent |
| parent = Parent(i) |
| |
| def Pop(self): |
| if(self.len == 0): |
| return None |
| if(self.nodeList[0].isConflicted): |
| |
| return None |
| |
| |
| nMin = self.nodeList[0] |
| self.idLocator[self.nodeList[0].id] = -1 |
| |
| |
| self.nodeList[0] = self.nodeList[self.len - 1] |
| self.idLocator[self.nodeList[0].id] = 0 |
| self.len -= 1 |
| self.Min_Heapify(0) |
| return nMin |
| |
| def Min_Heapify(self, i): |
| nMin = self.nodeList[i] |
| li = Left(i) |
| if(li < self.len): |
| if(self.nodeList[li].dist < nMin.dist): |
| nMin = self.nodeList[li] |
| min_i = li |
| ri = Right(i) |
| if(ri < self.len): |
| if(self.nodeList[ri].dist < nMin.dist): |
| nMin = self.nodeList[ri] |
| min_i = ri |
| if(nMin.id != self.nodeList[i].id): |
| self.Exchange(i, min_i) |
| self.Min_Heapify(min_i) |
| |
| def Delete(self, node): |
| i = self.idLocator[node.id] |
| self.nodeList[i].isConflicted = True |
| self.nodeList[i].dist = np.inf |
| self.Min_Heapify(i) |
| |
| def Build(self): |
| self.len = len(self.nodeList) |
| for i in range(int(Parent(self.len - 1)) + 1): |
| self.Min_Heapify(i) |
| |
| def Print(self): |
| i = 0 |
| level = 1 |
| ilimit = 0 |
| while(i < self.len): |
| print('N(%d, %2.1f)' % (self.nodeList[i].id, self.nodeList[i].dist), end = ' ') |
| i += 1 |
| if(i > ilimit): |
| print('\n') |
| level *= 2 |
| ilimit += level |
|
|
| """ |
| ################################################################################################ |
| ###################### IMPLEMENTATION OF PRIM'S ALGO FOR FINDING MST ########################## |
| ############################# USES HEAP DEFINED ABOVE ######################################## |
| ################################################################################################ |
| """ |
| def MST(nodelist, WScalarMat, conflicts_Dict, source): |
| |
| |
| mst_adj_graph = np.ndarray(WScalarMat.shape, np.bool)*False |
| |
| |
| for id in range(len(nodelist)): |
| nodelist[id].id = id |
| nodelist[id].dist = np.inf |
| nodelist[id].isConflicted = False |
| nodelist[id].src = -1 |
| |
| |
| nodelist[source].dist = 0 |
| for neighbour in range(len(nodelist)): |
| if neighbour != source: |
| nodelist[neighbour].dist = WScalarMat[source][neighbour] |
| nodelist[neighbour].src = source |
| h = Heap(nodelist) |
| |
| mst_nodes = defaultdict(lambda: []) |
| mst_nodes_bool = np.array([False]*len(nodelist)) |
| |
| |
| while True: |
| nextNode = h.Pop() |
| if nextNode == None: |
| break |
| print("next-id:"+str(nextNode.id)) |
| print('picked by '+str(nodelist[nextNode.id].dist)) |
| print() |
| |
| mst_nodes_bool[nextNode.id] = True |
| mst_nodes[nextNode.chunk_id].append(nextNode) |
|
|
|
|
| if nextNode.src != -1: |
| mst_adj_graph[nextNode.src, nextNode.id] = True |
| |
| nid = nextNode.id |
| for conId in conflicts_Dict[nid]: |
| h.Delete(nodelist[conId]) |
| for neighbour in range(len(nodelist)): |
| if neighbour != nextNode.id: |
| print(WScalarMat[nextNode.id][neighbour]) |
| print(nodelist[neighbour].dist) |
| h.Decrease_Key(nodelist[neighbour], WScalarMat[nextNode.id][neighbour], nextNode.id) |
|
|
| print(mst_nodes_bool) |
| |
| print('#'*30) |
| mst_nodes = dict(mst_nodes) |
|
|
| return (mst_nodes, mst_adj_graph, mst_nodes_bool) |
|
|
| def clique(nodelist, WScalarMat, conflicts_Dict, source): |
| |
| |
| mst_adj_graph = np.ndarray(WScalarMat.shape, np.bool)*False |
| |
| |
| |
| for id in range(len(nodelist)): |
| |
| nodelist[id].id = id |
| nodelist[id].dist = np.inf |
| nodelist[id].isConflicted = False |
| nodelist[id].src = -1 |
| |
| |
| nodelist[source].dist = 0 |
|
|
| nodeset=set() |
| for neighbour in range(len(nodelist)): |
| if neighbour != source: |
| nodelist[neighbour].dist = WScalarMat[source][neighbour] |
| nodelist[neighbour].src = source |
| |
|
|
| |
| nodeset.add((0,source)) |
| nodesadded=[] |
| nodesavailable = np.zeros(len(nodelist),dtype=int) |
| |
| mst_nodes = defaultdict(lambda: []) |
| mst_nodes_bool = np.array([False]*len(nodelist)) |
| |
| |
|
|
| it=0 |
| nextNode=-1 |
| while True: |
| |
| it+=1 |
| |
| if(it>1000): |
| break |
| if(len(nodeset)==0): |
| break |
| |
| |
| nextNode = next(iter(nodeset)) |
| |
| |
| |
| nextNode=nodelist[nextNode[1]] |
| |
| |
|
|
| |
| nodesavailable[nextNode.id]=1 |
| |
| if nextNode == None: |
| break |
| |
| mst_nodes_bool[nextNode.id] = True |
| mst_nodes[nextNode.chunk_id].append(nextNode) |
|
|
| nodeset = set() |
|
|
| if nextNode.src != -1: |
| mst_adj_graph[nextNode.src, nextNode.id] = True |
| |
| |
| nid = nextNode.id |
| nodesadded.append(nid) |
| for conId in conflicts_Dict[nid]: |
| |
| nodesavailable[conId]=1 |
| |
| |
| for neighbour in range(len(nodelist)): |
| |
| |
| if(nodesavailable[neighbour]==1): |
| continue |
| if neighbour != nextNode.id: |
| |
| edgewt=0 |
| |
| for nodepresent in nodesadded: |
| edgewt+=WScalarMat[nodepresent][neighbour] |
| |
| nodeset.add((edgewt,neighbour)) |
| |
|
|
| nodeset=sorted(nodeset) |
| |
| |
| |
| |
| |
| mst_nodes = dict(mst_nodes) |
| if(it>1000): |
| print('!!!!*10') |
| for i in range(len(mst_nodes_bool)): |
| for j in range(len(mst_nodes_bool)): |
| if(i==j): |
| continue |
| if(mst_nodes_bool[i] and mst_nodes_bool[j]): |
| mst_adj_graph[i][j]=True |
| mst_adj_graph[j][i]=True |
|
|
| |
| |
| return (mst_nodes, mst_adj_graph, mst_nodes_bool) |
|
|
|
|
| def bron(R,P,X,nodelist,conflicts_Dict,level): |
| L = [] |
| if(len(P)==0 and len(X)==0): |
| L.append(R) |
| return L |
| |
| |
| |
| |
| |
| |
| Pit = P.copy() |
| |
| for v in Pit: |
| |
| R1 = R.copy() |
| P1 = P.copy() |
| X1 = X.copy() |
| R1.add(v) |
| for i in conflicts_Dict[v]: |
| if(i in P1): |
| P1.remove(i) |
| if(i in X1): |
| X1.remove(i) |
| if(v in P1): |
| P1.remove(v) |
| if(v in X1): |
| X1.remove(v) |
| G = bron(R1,P1,X1,nodelist,conflicts_Dict,level+1) |
| if(v in P): |
| P.remove(v) |
| X.add(v) |
| for i in G: |
| L.append(i) |
| return L |
|
|
| def RandomST_GoldOnly(nodelist, WScalarMat, conflicts_Dict, source): |
| (mst_nodes, mst_adj_graph, mst_nodes_bool) = MST(nodelist, WScalarMat, conflicts_Dict, source) |
|
|
| mst_adj_graph = np.zeros_like(mst_adj_graph) |
| nodelen = len(nodelist) |
| |
| |
| free_set = list(range(nodelen)) |
| full_set = list(range(nodelen)) |
| st_set = [] |
| start_node = np.random.randint(nodelen) |
| st_set.append(start_node) |
| free_set.remove(start_node) |
| for x in range(nodelen - 1): |
| a = st_set[np.random.randint(len(st_set))] |
| b = free_set[np.random.randint(len(free_set))] |
| if b not in st_set: |
| st_set.append(b) |
| free_set.remove(b) |
| mst_adj_graph[a, b] = 1 |
| |
| |
| return (mst_nodes, mst_adj_graph, mst_nodes_bool) |
|
|
|
|
| def GetMSTWeight(mst_adj_graph, WScalarMat): |
| return np.sum(WScalarMat[mst_adj_graph]) |
|
|