-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathwaterfilling.py
114 lines (96 loc) · 2.87 KB
/
waterfilling.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import numpy as np
import networkx as nx
import random
from random import shuffle
from itertools import islice
import sys
import time
def rank (cap, maxSet, secMaxSet):
largest = -sys.maxsize-1
secLargest = -sys.maxsize-1
for i in range(len(cap)):
if (cap[i] > largest):
secLargest = largest
largest = cap[i]
elif (cap[i] > secLargest and cap[i] != largest):
secLargest = cap[i]
for i in range(len(cap)):
if (cap[i] == largest):
maxSet.append(i)
if (cap[i] == secLargest):
secMaxSet.append(i)
if (secLargest == -sys.maxsize-1):
return 0;
return largest-secLargest
def set_credits (val, mins):
sum = 0
for i in mins:
sum += i
if val > sum:
return mins
remainder = val
minsCopy = list(mins)
res = [0]*len(minsCopy)
creditsToAssign = 0
diff = 0
while (remainder > 0):
maxSet = []
secMaxSet = []
diff = rank(minsCopy, maxSet, secMaxSet)
creditsToAssign = diff if (remainder > len(maxSet)*diff) else (remainder/len(maxSet))
if (diff == 0):
creditsToAssign = remainder/len(minsCopy)
for index in maxSet:
res[index] += creditsToAssign
minsCopy[index] -= creditsToAssign
remainder -= creditsToAssign * len(maxSet)
return res
def routing(G, cur_payments):
k = 4
throughput = 0
num_delivered = 0
index = 0
total_probing_messages = 0
total_max_path_length = 0
transaction_fees = 0
for payment in cur_payments:
fee = 0
src = payment[0]
dst = payment[1]
payment_size = payment[2]
path_set = list(nx.edge_disjoint_paths(G, src, dst))
index += 1
if (len(path_set) > k):
path_set = path_set[0:k]
max_path_length = 0
path_cap = [sys.maxsize]*len(path_set)
index_p = 0
for path in path_set:
total_probing_messages += len(path)-1
if len(path)-1 > max_path_length:
max_path_length = len(path)-1
for i in range(len(path)-1):
path_cap[index_p] = np.minimum(path_cap[index_p], G[path[i]][path[i+1]]["capacity"])
index_p += 1
res = set_credits(payment_size, path_cap)
index_p = 0
for path in path_set:
for i in range(len(path)-1):
G[path[i]][path[i+1]]["capacity"] -= res[index_p]
G[path[i+1]][path[i]]["capacity"] += res[index_p]
fee += G[path[i]][path[i+1]]["cost"]*res[index_p]
index_p += 1
if sum(res) < payment[2]-1e-6:
for i in range(len(path_set)):
p = path_set[i]
for j in range(len(p)-1):
G[p[j]][p[j+1]]["capacity"] += res[i]
G[p[j+1]][p[j]]["capacity"] -= res[i]
# remove atomicity
# throughput += sum(res)
else:
num_delivered += 1
throughput += payment[2]
total_max_path_length += max_path_length
transaction_fees += fee
return throughput, transaction_fees/throughput, num_delivered, total_probing_messages, total_max_path_length