-
Notifications
You must be signed in to change notification settings - Fork 0
/
student_utils.py
120 lines (92 loc) · 4.03 KB
/
student_utils.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
import networkx as nx
import numpy as np
def decimal_digits_check(number):
number = str(number)
parts = number.split('.')
if len(parts) == 1:
return True
else:
return len(parts[1]) <= 5
def data_parser(input_data):
number_of_locations = int(input_data[0][0])
number_of_houses = int(input_data[1][0])
list_of_locations = input_data[2]
list_of_houses = input_data[3]
starting_location = input_data[4][0]
adjacency_matrix = [[entry if entry == 'x' else float(entry) for entry in row] for row in input_data[5:]]
return number_of_locations, number_of_houses, list_of_locations, list_of_houses, starting_location, adjacency_matrix
def adjacency_matrix_to_graph(adjacency_matrix):
node_weights = [adjacency_matrix[i][i] for i in range(len(adjacency_matrix))]
adjacency_matrix_formatted = [[0 if entry == 'x' else entry for entry in row] for row in adjacency_matrix]
for i in range(len(adjacency_matrix_formatted)):
adjacency_matrix_formatted[i][i] = 0
# print(adjacency_matrix_formatted)
G = nx.convert_matrix.from_numpy_matrix(np.matrix(adjacency_matrix_formatted))
message = ''
for node, datadict in G.nodes.items():
if node_weights[node] != 'x':
message += 'The location {} has a road to itself. This is not allowed.\n'.format(node)
datadict['weight'] = node_weights[node]
return G, message
def is_metric(G):
shortest = dict(nx.floyd_warshall(G))
for u, v, datadict in G.edges(data=True):
if abs(shortest[u][v] - datadict['weight']) >= 0.00001:
print(u, v)
return False
return True
def adjacency_matrix_to_edge_list(adjacency_matrix):
edge_list = []
for i in range(len(adjacency_matrix)):
for j in range(len(adjacency_matrix[0])):
if adjacency_matrix[i][j] == 1:
edge_list.append((i, j))
return edge_list
def is_valid_walk(G, closed_walk):
if len(closed_walk) == 2:
return closed_walk[0] == closed_walk[1]
# return all([(closed_walk[i], closed_walk[i+1]) in G.edges for i in range(len(closed_walk) - 1)])
for i in range(len(closed_walk) - 1):
if (closed_walk[i], closed_walk[i+1]) not in G.edges:
print((closed_walk[i], closed_walk[i+1]))
return False
return True
def get_edges_from_path(path):
return [(path[i], path[i+1]) for i in range(len(path) - 1)]
"""
G is the adjacency matrix.
car_cycle is the cycle of the car in terms of indices.
dropoff_mapping is a dictionary of dropoff location to list of TAs that got off at said droppoff location
in terms of indices.
"""
def cost_of_solution(G, car_cycle, dropoff_mapping):
cost = 0
message = ''
dropoffs = dropoff_mapping.keys()
if not is_valid_walk(G, car_cycle):
message += 'This is not a valid walk for the given graph.\n'
cost = 'infinite'
if not car_cycle[0] == car_cycle[-1]:
message += 'The start and end vertices are not the same.\n'
cost = 'infinite'
if cost != 'infinite':
if len(car_cycle) == 1:
car_cycle = []
else:
car_cycle = get_edges_from_path(car_cycle[:-1]) + [(car_cycle[-2], car_cycle[-1])]
if len(car_cycle) != 1:
driving_cost = sum([G.edges[e]['weight'] for e in car_cycle]) * 2 / 3
else:
driving_cost = 0
walking_cost = 0
shortest = dict(nx.floyd_warshall(G))
for drop_location in dropoffs:
for house in dropoff_mapping[drop_location]:
walking_cost += shortest[drop_location][house]
message += f'The driving cost of your solution is {driving_cost:.4f}.\n'
message += f'The walking cost of your solution is {walking_cost:.4f}.\n\n'
cost = driving_cost + walking_cost
message += f'The total cost of your solution is {cost}.\n'
return cost, message
def convert_locations_to_indices(list_to_convert, list_of_locations):
return [list_of_locations.index(name) if name in list_of_locations else None for name in list_to_convert]