Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

greedy_solver.py 3.7 KB

You have to be logged in to leave a comment. Sign In
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
  1. import os
  2. import pandas as pd
  3. from problems.vrp.problem_vrp import CVRP
  4. import torch
  5. from torch.utils.data import DataLoader
  6. import math
  7. shift_time = 1200
  8. # Note, this function also updates the cur_time in cases of idle
  9. def find_nearest(prev, coords, mask):
  10. min_dist, min_index = torch.ones(coords.shape[0], dtype=float) * 10000, torch.ones(coords.shape[0], dtype=int) * -1
  11. for j in range(coords.shape[0]):
  12. for i in range(coords.shape[1]):
  13. if ~mask.squeeze()[j][i]:
  14. dist_eu = math.sqrt((coords[j][prev[j]][0] - coords[j][i][0]) ** 2 + (coords[j][prev[j]][1] - coords[j][i][1]) ** 2)
  15. if dist_eu < min_dist[j]: # and dist_eu < min_dist:
  16. min_index[j] = i
  17. min_dist[j] = dist_eu
  18. assert min_index[j] > -1, 'could not find any available node'
  19. return min_index
  20. def get_route(input):
  21. sequences = []
  22. state = CVRP.make_state(input, visited_dtype=torch.uint8)
  23. state.initialize(input)
  24. # Perform decoding steps
  25. i, batch_size = 0, input['loc'].shape[0]
  26. # max_route_length = int(len(input['tos'][1]) * 1.5)
  27. prev = torch.zeros(batch_size, dtype=int) # start at the Depo
  28. while not (state.all_finished()):
  29. if i > 150:
  30. print('Too many iterations. i = {}. Breaking'.format(i))
  31. break # TODO: Shouldent happen - or allow Unassigned tasks
  32. mask = state.get_mask()
  33. selected = find_nearest(prev, state.coords, mask) #
  34. state = state.update(selected)
  35. sequences.append(selected)
  36. prev = selected
  37. i += 1
  38. # Collected lists, return Tensor
  39. return sequences, state.get_final_cost()
  40. def persist_results(pi_i, input_data, arrive_at, output_folder=None):
  41. l = [i[0].numpy().item(0) for i in pi_i]
  42. l.insert(0, 0) # Insert the Depot at the beginning
  43. l.append(0)
  44. df = pd.DataFrame({'loc_id': l, 'lat': 0.0, 'lng': 0.0, 'drive_time': 0.0,
  45. 'arrive_at': 0.0, 'TOS': 0, 'tw_start': 0, 'tw_end': 0})
  46. for index, row in df.iterrows():
  47. if 'original_loc' in input_data.keys():
  48. cur_point = input_data['original_loc'][l[index]]
  49. else:
  50. cur_point = input_data['loc'][l[index] - 1]
  51. cur_tw = input_data['tw'][l[index] - 1]
  52. df.lng.at[index], df.lat.at[index] = cur_point[1], cur_point[0]
  53. df.TOS.at[index] = input_data['tos'][l[index]]
  54. if index < len(l) - 1:
  55. df.arrive_at.at[index] = float(arrive_at[index - 1])
  56. df.drive_time.at[index] = input_data['wmat'][l[index - 1]][l[index]]
  57. if l[index] > 0:
  58. df.tw_start.at[index], df.tw_end.at[index] = cur_tw[0], cur_tw[1]
  59. df.arrive_at[0] = 0.0
  60. cost = str(int(df.drive_time.sum()))
  61. if output_folder is not None:
  62. file = os.path.join(output_folder, 'input_table_' + cost + '.csv')
  63. df.to_csv(file)
  64. route = os.path.join(output_folder, 'greedy_map_' + cost + '.htm')
  65. # out = save_df_on_map(df, output_file=route, persist_map=True, is_jsprit=False)
  66. return df
  67. # def get_cost(input, sequence):
  68. # lambda input, pi: self.problem.get_costs(input[0], pi)
  69. def get_costs(dataset, pi):
  70. loc_with_depot = torch.cat((dataset['depot'][:, None, :], dataset['loc']), 1)
  71. d = loc_with_depot.gather(1, pi[..., None].expand(*pi.size(), loc_with_depot.size(-1)))
  72. # Length is distance (L2-norm of difference) of each next location to its prev and of first and last to depot
  73. return (
  74. (d[:, 1:] - d[:, :-1]).norm(p=2, dim=2).sum(1)
  75. + (d[:, 0] - dataset['depot']).norm(p=2, dim=1) # Depot to first
  76. + (d[:, -1] - dataset['depot']).norm(p=2, dim=1) # Last to depot, will be 0 if depot is last
  77. ), None
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...