From 9596df80af810c1dd7db9d74d24ef43bbceeaf3b Mon Sep 17 00:00:00 2001 From: Daniel Gyulai Date: Tue, 19 Jan 2021 17:44:27 +0100 Subject: [PATCH] working path --- VNE7.txt | 4 ++ VNR1.txt | 3 + VNR2.txt | 3 + matrix.py | 80 ++++++++++++++++++++++++++ noderank.py | 97 +++++++++++++++++++++++++++++++ test.py | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 350 insertions(+) create mode 100644 VNE7.txt create mode 100644 VNR1.txt create mode 100644 VNR2.txt create mode 100644 matrix.py create mode 100644 noderank.py create mode 100644 test.py diff --git a/VNE7.txt b/VNE7.txt new file mode 100644 index 0000000..9a60484 --- /dev/null +++ b/VNE7.txt @@ -0,0 +1,4 @@ +0.0,0.0,7,0,4,9,0 +0.0,0.0,9,4,0,5,3 +0.0,0.0,9,9,5,0,5 +0.0,0.0,6,0,3,5,0 \ No newline at end of file diff --git a/VNR1.txt b/VNR1.txt new file mode 100644 index 0000000..8687c81 --- /dev/null +++ b/VNR1.txt @@ -0,0 +1,3 @@ +0.0,0.0,3,0,1,0 +0.0,0.0,7,1,0,5 +0.0,0.0,4,0,5,0 \ No newline at end of file diff --git a/VNR2.txt b/VNR2.txt new file mode 100644 index 0000000..ade516c --- /dev/null +++ b/VNR2.txt @@ -0,0 +1,3 @@ +0.0,0.0,3,0,1,3 +0.0,0.0,2,1,0,8 +0.0,0.0,5,3,8,0 \ No newline at end of file diff --git a/matrix.py b/matrix.py new file mode 100644 index 0000000..175fd4d --- /dev/null +++ b/matrix.py @@ -0,0 +1,80 @@ +def zeroes(n, m): + result = [] + # iterate through rows of X + for i in range(n): + a = [] + # iterate through columns of Y + for j in range(m): + a.append(0.0) + result.append(a) + return result + +def diag(value, n): + ret = [] + for i in range(n): + a = [] + for j in range(n): + if i == j: + a.append(float(value)) + else: + a.append(0.0) + ret.append(a) + return ret + +# Matrix multiplication +def mm(X, Y): + result = zeroes(len(X), len(Y[0])) + for i in range(len(X)): + for j in range(len(Y[0])): + for k in range(len(Y)): + result[i][j] += X[i][k] * Y[k][j] + return result +# Matrix addition +def ma(X, Y): + result = [] + for i in range(len(X)): + temp_row = [] + for j in range(len(X[i])): + temp_row.append(X[i][j] + Y[i][j]) + result.append(temp_row) + return result + +def m_delta(X,Y): + diff = [] + for i in range(len(X)): + for j in range(len(X[0])): + diff.append(X[i][j] - Y[i][j]) + return abs(sum(diff) / len(diff)) + +def asstet_matrix(a, b): + if len(a) == len(b): + for i in range(len(a)): + if len(a[i]) == len(b[i]): + for j in range(len(a)): + if a[i][j] != b[i][j]: + raise Exception("Assertion error!\n{}\n{}".format(a,b)) + else: + raise Exception("Assertion error!\n{}\n{}".format(a,b)) + else: + raise Exception("Assertion error!\n{}\n{}".format(a,b)) + +def test_mm(): + a = [[1, 2, 3], [4, 5, 6]] + b = [[7, 8], [9, 10], [11, 12]] + result = mm(a, b) + ref = [[58, 64], [139, 154]] + asstet_matrix(result, ref) + print("test_mm: passed") + +def test_ma(): + a = [[3, 4], [2, 1]] + b = [[1, 5],[3, 7]] + result = ma(a, b) + ref = [[4, 9], [5, 8]] + asstet_matrix(result, ref) + print("test_ma: passed") + + +if __name__ == "__main__": + test_mm() + test_ma() diff --git a/noderank.py b/noderank.py new file mode 100644 index 0000000..5268ca3 --- /dev/null +++ b/noderank.py @@ -0,0 +1,97 @@ +import matrix + + + + +class Noderank: + def __init__(self, source): + self.node_pos = [] + self.node_cpu = [] + self.node_matrix = [] + self.ranks = {} + + with open(source) as f: + for i in f: + d = i.split(',') + if len(d) > 1: + self.node_pos.append([float(d[0]), float(d[1])]) + self.node_cpu.append(float(d[2])) + a = [] + for j in d[3:]: + a.append(float(j)) + self.node_matrix.append(a) + temp = [] + for i in self.node_rank(): + temp.append([len(temp), i[0]]) + temp.sort(key = lambda a: a[1], reverse=True) + self.ranks = [] + for i in temp: + self.ranks.append(i[0]) + + def H(self, u): + return self.node_cpu[u] * sum(self.node_matrix[u]) + + def sum_H(self): + sum_h = 0.0 + for u in range(len(self.node_matrix)): + sum_h += self.H(u) + return sum_h + + def nbr_H_sum(self, u): + ret = 0.0 + for i in range(len(self.node_matrix[u])): + if self.node_matrix[u][i] > 0: + ret += self.H(i) + return ret + + def pf(self, u,v): + return self.H(v) / self.nbr_H_sum(u) + + def pj(self, u,v): + return self.H(v) / self.sum_H() + + def T(self): + puj = 0.015 + puf = 0.085 + + + m_pjuv = [] + for i in range(len(self.node_matrix)): + a = [] + for j in range(len(self.node_matrix[i])): + a.append(self.pj(i,j)) + m_pjuv.append(a) + + m_pfuv = [] + for i in range(len(self.node_matrix)): + a = [] + for j in range(len(self.node_matrix[i])): + if i == j: + a.append(0) + else: + a.append(self.pf(i,j)) + m_pfuv.append(a) + T1 = matrix.mm(m_pjuv, matrix.diag(puj, len(self.node_matrix))) + T2 = matrix.mm(m_pfuv, matrix.diag(puf, len(self.node_matrix))) + return matrix.ma(T1, T2) + + def node_rank(self): + NR = [] + sum_h = self.sum_H() + for u in range(len(self.node_matrix)): + NR.append([self.H(u) / sum_h]) + e = 0.0001 + #print("Iterative, e={}".format(e)) + for i in range(50): + NR_t = matrix.mm(self.T(), NR) + d = matrix.m_delta(NR_t, NR) + #print(d) + NR = NR_t + if d < e: + return NR + print("ERROR: node_rank could not stop after 50 iterations") + return NR + +if __name__ == "__main__": + n = Noderank("DOOAB4.txt") + print(n.ranks) \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000..4092cc1 --- /dev/null +++ b/test.py @@ -0,0 +1,163 @@ +from noderank import Noderank + +class VNR: + def __init__(self): + self.nodes = {} # vNodeID: [pNode, cpu] + self.links = [] # List of list, [] + +class Path: + def __init__(self): + self.path = [] + self.weight = 0 + + def copy(self): + p = Path() + p.weight = self.weight + for i in self.path: + p.path.append(i) + return p + + +def load_vn(source): + return Noderank(source) + +def getVNR(network, source): + n = Noderank(source) + + +def node_map(network, request): + pairing = {} # key: vNodeID, value: nodeID + + for vnr_node_id in range(len(request.node_cpu)): + #print("Processing VRN node rew of CPU {}".format(request.node_cpu[vnr_node_id])) + for rank_id in range(len(network.ranks)): + node = network.ranks[rank_id] + tmp_node_cpu = network.node_cpu[node] + # subtract assigned capacity - only commit if placement is possible + for k, v in pairing.items(): + if v == node: + tmp_node_cpu -= request.node_cpu[k] + print(" {} Available: {}".format(node, tmp_node_cpu)) + if tmp_node_cpu >= request.node_cpu[vnr_node_id]: + print("VRN node {} placed on node {}".format(vnr_node_id, node)) + pairing[vnr_node_id] = node + #network.node_cpu[node] -= request.node_cpu[vnr_node_id] + break + if len(pairing) == len(request.node_cpu): + vnr = VNR() + for v, p in pairing.items(): + vnr.nodes[v] = [p, request.node_cpu[v]] + return vnr + return None + +def min_index(array, Q): + max_val = -1 + max_ind = None + for i in range(len(array)): + if Q[i] is not None: + if array[i] > max_val: + max_val = array[i] + max_ind = i + return max_ind + +def all_none(array): + for i in array: + if i is not None: + return False + return True + + +# data - list of lists, each item contains the next hops for a given index +# s - int index, current source node for one iteration +def make_paths(data, paths): + new_paths = [] + expanded = False + for p in paths: + p_end = p[-1] + for i in data[p[-1]]: + #print(i) + temp_path = [] + temp_path.extend(p) + if i not in temp_path: + temp_path.append(i) + expanded = True + new_paths.append(temp_path) + + #if expanded: + if len(new_paths) > 0: + new_paths.extend(make_paths(data, new_paths)) + return new_paths + else: + return new_paths + + + +# network - Noderank +# source - int index +# dest - int index +def path_finder(network, source, dest): + # Dijkstra + Q = [] + dist = [] + prev = [] + for i in range(len(network.node_matrix)): + dist.append(9999999999) + prev.append([]) + Q.append(i) + dist[source] = 0 + + while not all_none(Q) > 0: + u = min_index(dist, Q) + Q[u] = None + #print(Q) + #print(u) + + for v in range(len(network.node_matrix)): + if network.node_matrix[u][v] > 0: # if U and V are neighbours + prev[v].append(u) + + if u == dest: + break + # Paths from next hops + paths = [] + for p in make_paths(prev, [[source]]): + if p[0] == source and p[-1] == dest: + path = Path() + path.path = p + for i in range(len(p)-1): + path.weight += network.node_matrix[p[i]][p[i+1]] + paths.append(path) + #print("{0}: {1}".format(path.path, path.weight)) + paths.sort(key=lambda p: p.weight) + return paths + + + + +def nw_map(network, vnr, request): + # k shortest path between vnr assigned nodes + pass + + +if __name__ == "__main__": + network = Noderank("VNE7.txt") + print(network.ranks) + request = Noderank("VNR1.txt") + paths = path_finder(network, 0, 3) + for path in paths: + print("{0}: {1}".format(path.path, path.weight)) + exit(0) + vnr = node_map(network, request) + if vnr is None: + print("Can't assign VNR1! Not enough CPU.") + else: + if nw_map: + pass + else: + print("Can't assign VNR1! Not enough network.") + + + + + +