-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
139 lines (112 loc) · 4.84 KB
/
main.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# The input file is in the format:
# Number of cities: A B C D ...(N cities)
# Cost/Reliability matrix: A-B,A-C,A-D...B-C,B-D...C-D....(N(N-1)/2)
'''
usage: main.py [-h] [-f FILE_PATH] -r RELIABILITY_GOAL -c COST_CONSTRAINT
optional arguments:
-h, --help show this help message and exit
-f FILE_PATH, --input-file FILE_PATH
InputFile to work on
-r RELIABILITY_GOAL, --reliability-goal RELIABILITY_GOAL
the reliability goal of the network
-c COST_CONSTRAINT, --cost-constraint COST_CONSTRAINT
the cost constraint of the network
'''
from mst import MST
from edge_generator import EdgeGenerator
from argparse import ArgumentParser
from rel_calculator import RelCalculator
class Main:
@staticmethod
def parseArgs():
parser = ArgumentParser()
parser.add_argument('-f', '--input-file', action='store', type=str,
dest='file_path', help='InputFile to work on', default='input.txt')
parser.add_argument('-r', '--reliability-goal', action='store', dest='reliability_goal',
help='the reliability goal of the network', type=float, required=True)
parser.add_argument('-c', '--cost-constraint', action='store', dest='cost_constraint',
help='the cost constraint of the network', type=float, required=True)
return parser.parse_args()
@staticmethod
def show_mst(cities, edges):
# generate the limits of the problem
mst = MST(cities, edges)
min_cost_tree, min_cost = mst.min_cost_tree()
max_reliability_tree, max_rel = mst.max_rel_tree()
# print trees for debugging
print("min cost tree")
print(min_cost_tree)
print("min cost tree value is {}".format(min_cost))
print('\n')
print("max reliability tree")
print(max_reliability_tree)
print("max reliability tree value is {}".format(max_rel))
print('\n')
return min_cost_tree
@staticmethod
def optimal_solution(cities, edges, cost_constraint, reliability_goal, initial_solution):
def attemptAcceptance(cost, costgoal, rel, relgoal):
return (cost <= costgoal and rel >= relgoal)
def sumCost(edges):
return sum(map(lambda x: x.c, edges))
# start from min_cost tree and build up
rel_calculator = RelCalculator(cities)
graph = initial_solution
cost = sumCost(graph)
rel = rel_calculator.recursive_rel(graph, [])
while(cost <= cost_constraint and rel < reliability_goal and len(graph) < len(cities)):
unadded_edges = [item for item in edges if item not in graph]
solutions_list = []
for unadded_edge in unadded_edges:
sol_cost = sumCost(graph + [unadded_edge])
if(sol_cost < cost_constraint):
solutions_list.append((
sol_cost,
rel_calculator.recursive_rel(graph + [unadded_edge], []),
unadded_edge
))
best_candidate = None
best_ratio = None
for c,r,e in solutions_list:
if (best_candidate == None or (r/c) > best_ratio):
best_ratio = r /c
best_candidate = e
if best_candidate == None:
break
else:
graph.append(best_candidate)
cost = sumCost(graph)
rel = rel_calculator.recursive_rel(graph, [])
if(attemptAcceptance(cost, cost_constraint, rel, reliability_goal)):
print("Solution was found with reliability of {} and cost of {}".format(rel, cost))
print("Solution: \n")
print(graph)
else:
print("The problem is unfeasable and no solution was found")
@staticmethod
def printInput(cities, edges):
# print cities and edges for debugging purposes
print("list of cities and edges")
print(cities)
print(edges)
print('\n')
@staticmethod
def main():
result = None
try:
result = Main.parseArgs()
except Exception as e:
print(e)
exit()
file_path = result.file_path
reliability_goal = result.reliability_goal + 1e-10 # add epsilon for numerical stability
cost_constraint = result.cost_constraint + 1e-10
cities, edges = EdgeGenerator.generate(file_path)
# show Input
Main.printInput(cities, edges)
# show MST calculations
initial_solution = Main.show_mst(cities, edges)
# find the optimal solution
Main.optimal_solution(cities, edges, cost_constraint, reliability_goal, initial_solution)
if __name__ == "__main__":
Main.main()