a-ragab-h-m commited on
Commit
286963d
·
verified ·
1 Parent(s): 9e1f7df

Upload 4 files

Browse files
google_solver/Untitled.ipynb ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 3,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import numpy as np\n",
10
+ "import torch"
11
+ ]
12
+ },
13
+ {
14
+ "cell_type": "code",
15
+ "execution_count": 6,
16
+ "metadata": {},
17
+ "outputs": [
18
+ {
19
+ "data": {
20
+ "text/plain": [
21
+ "[array([0.01560026, 0.14899027, 0.8198149 ], dtype=float32),\n",
22
+ " array([0.9768128 , 0.06915247, 0.42297667], dtype=float32),\n",
23
+ " array([0.9447805 , 0.9968865 , 0.85253155], dtype=float32),\n",
24
+ " array([0.4674251, 0.9449542, 0.6850118], dtype=float32),\n",
25
+ " array([0.8488321 , 0.9191937 , 0.33687925], dtype=float32)]"
26
+ ]
27
+ },
28
+ "execution_count": 6,
29
+ "metadata": {},
30
+ "output_type": "execute_result"
31
+ }
32
+ ],
33
+ "source": [
34
+ "torch.rand(5, 3).numpy()"
35
+ ]
36
+ },
37
+ {
38
+ "cell_type": "code",
39
+ "execution_count": 7,
40
+ "metadata": {},
41
+ "outputs": [],
42
+ "source": [
43
+ "x = torch.rand(5, 3).numpy()"
44
+ ]
45
+ },
46
+ {
47
+ "cell_type": "code",
48
+ "execution_count": 8,
49
+ "metadata": {},
50
+ "outputs": [
51
+ {
52
+ "data": {
53
+ "text/plain": [
54
+ "[[0.6611388, 0.24161768, 0.35973948],\n",
55
+ " [0.28449154, 0.81414443, 0.17932409],\n",
56
+ " [0.65817285, 0.1036877, 0.8726997],\n",
57
+ " [0.05815494, 0.3649323, 0.6273505],\n",
58
+ " [0.57139295, 0.16107935, 0.08857018]]"
59
+ ]
60
+ },
61
+ "execution_count": 8,
62
+ "metadata": {},
63
+ "output_type": "execute_result"
64
+ }
65
+ ],
66
+ "source": [
67
+ "[list(x[i]) for i in range(x.shape[0])]"
68
+ ]
69
+ },
70
+ {
71
+ "cell_type": "code",
72
+ "execution_count": null,
73
+ "metadata": {},
74
+ "outputs": [],
75
+ "source": []
76
+ }
77
+ ],
78
+ "metadata": {
79
+ "kernelspec": {
80
+ "display_name": "Python 3",
81
+ "language": "python",
82
+ "name": "python3"
83
+ },
84
+ "language_info": {
85
+ "codemirror_mode": {
86
+ "name": "ipython",
87
+ "version": 3
88
+ },
89
+ "file_extension": ".py",
90
+ "mimetype": "text/x-python",
91
+ "name": "python",
92
+ "nbconvert_exporter": "python",
93
+ "pygments_lexer": "ipython3",
94
+ "version": "3.7.3"
95
+ }
96
+ },
97
+ "nbformat": 4,
98
+ "nbformat_minor": 2
99
+ }
google_solver/convert_data.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import torch
3
+ import numpy as np
4
+
5
+
6
+ def convert_tensor(x):
7
+ x = x.long().numpy().astype('int')
8
+
9
+ if len(x.shape) == 1:
10
+ return list(x)
11
+ else:
12
+ return [list(x[i]) for i in range(x.shape[0])]
13
+
14
+
15
+
16
+ def make_time_windows(start_time, end_time):
17
+ return torch.cat([start_time, end_time], dim=2)
18
+
19
+
20
+
21
+ def convert_data(input, scale_factor):
22
+
23
+ graph_data, fleet_data = input
24
+
25
+ start_times = graph_data['start_times']
26
+ end_times = graph_data['end_times']
27
+
28
+ distance_matrix = graph_data['distance_matrix']
29
+ time_matrix = graph_data['time_matrix']
30
+
31
+ time_windows = make_time_windows(start_times, end_times)
32
+
33
+
34
+ batch_size = distance_matrix.shape[0]
35
+ data = []
36
+ for i in range(batch_size):
37
+
38
+ num_vehicles = distance_matrix[i].shape[1]
39
+
40
+ space_mat = distance_matrix[i] * scale_factor
41
+ time_mat = time_matrix[i] * scale_factor
42
+ windows = time_windows[i] * scale_factor
43
+
44
+ space_mat = convert_tensor(space_mat)
45
+ time_mat = convert_tensor(time_mat)
46
+ windows = convert_tensor(windows)
47
+
48
+
49
+ D = {'distance_matrix': space_mat,
50
+ 'time_matrix': time_mat,
51
+ 'time_windows': windows,
52
+ 'depot': 0,
53
+ 'num_vehicles': num_vehicles
54
+ }
55
+
56
+ data.append(D)
57
+ return data
google_solver/google_model.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import print_function
2
+ from ortools.constraint_solver import routing_enums_pb2
3
+ from ortools.constraint_solver import pywrapcp
4
+ import torch
5
+ from google_solver.convert_data import convert_data
6
+
7
+
8
+ class GoogleActor(object):
9
+
10
+ def __init__(self, scale_factor=100):
11
+
12
+ if scale_factor is None:
13
+ self.scale_factor = 1
14
+ else:
15
+ self.scale_factor = scale_factor
16
+
17
+
18
+ def __call__(self, input):
19
+
20
+ drive_times = []
21
+ data = convert_data(input, self.scale_factor)
22
+ batch_size = len(data)
23
+ for datum in data:
24
+ routing, assignment = self.compute_route(datum)
25
+ total_time = self.compute_total_time(datum, routing, assignment)
26
+ drive_times.append(total_time)
27
+
28
+ drive_times = torch.tensor(drive_times).float()
29
+ return drive_times
30
+
31
+
32
+ def compute_distance(self, routing, assignment, num_nodes):
33
+ """Prints solution on console."""
34
+ cumulative_route_distance = 0
35
+ for vehicle_id in range(num_nodes):
36
+ index = routing.Start(vehicle_id)
37
+ route_distance = 0
38
+ while not routing.IsEnd(index):
39
+ previous_index = index
40
+ index = assignment.Value(routing.NextVar(index))
41
+ route_distance += routing.GetArcCostForVehicle(
42
+ previous_index, index, vehicle_id)
43
+ cumulative_route_distance += route_distance
44
+
45
+ cumulative_route_distance = cumulative_route_distance / self.scale_factor
46
+ return cumulative_route_distance
47
+
48
+
49
+ def compute_total_time(self, data, routing, assignment):
50
+ time_dimension = routing.GetDimensionOrDie('Time')
51
+ total_time = 0
52
+ for vehicle_id in range(data['num_vehicles']):
53
+ index = routing.Start(vehicle_id)
54
+ while not routing.IsEnd(index):
55
+ index = assignment.Value(routing.NextVar(index))
56
+ time_var = time_dimension.CumulVar(index)
57
+ total_time += assignment.Min(time_var)
58
+ total_time = total_time/self.scale_factor
59
+ return total_time
60
+
61
+
62
+
63
+ def compute_route(self, input):
64
+
65
+ distance_matrix = input['distance_matrix']
66
+ time_matrix = input['time_matrix']
67
+ time_windows = input['time_windows']
68
+ num_vehicles = input['num_vehicles']
69
+ depot = input['depot']
70
+
71
+
72
+ manager = pywrapcp.RoutingIndexManager(len(time_matrix), num_vehicles, depot)
73
+ routing = pywrapcp.RoutingModel(manager)
74
+
75
+ def time_callback(from_index, to_index):
76
+ """Returns the travel time between the two nodes."""
77
+ # Convert from routing variable Index to time matrix NodeIndex.
78
+ from_node = manager.IndexToNode(from_index)
79
+ to_node = manager.IndexToNode(to_index)
80
+ return time_matrix[from_node][to_node]
81
+
82
+ transit_callback_index = routing.RegisterTransitCallback(time_callback)
83
+ routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
84
+ time = 'Time'
85
+ routing.AddDimension(
86
+ transit_callback_index,
87
+ 10000, # allow waiting time
88
+ 10000, # maximum time per vehicle
89
+ False, # Don't force start cumul to zero.
90
+ time)
91
+
92
+ time_dimension = routing.GetDimensionOrDie(time)
93
+ # Add time window constraints for each location except depot.
94
+ for location_idx, time_window in enumerate(time_windows):
95
+ if location_idx == 0:
96
+ continue
97
+ index = manager.NodeToIndex(location_idx)
98
+ a, b = int(time_window[0]), int(time_window[1])
99
+ time_dimension.CumulVar(index).SetRange(a, b)
100
+
101
+ # Add time window constraints for each vehicle start node.
102
+ for vehicle_id in range(num_vehicles):
103
+ index = routing.Start(vehicle_id)
104
+ a, b = int(time_windows[0][0]), int(time_windows[0][1])
105
+ time_dimension.CumulVar(index).SetRange(a, b)
106
+
107
+ for i in range(num_vehicles):
108
+ routing.AddVariableMinimizedByFinalizer(
109
+ time_dimension.CumulVar(routing.Start(i)))
110
+ routing.AddVariableMinimizedByFinalizer(
111
+ time_dimension.CumulVar(routing.End(i)))
112
+
113
+ search_parameters = pywrapcp.DefaultRoutingSearchParameters()
114
+ search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC)
115
+ assignment = routing.SolveWithParameters(search_parameters)
116
+
117
+ return routing, assignment
118
+
119
+
120
+
121
+
122
+ def evaluate_google_model(validation_dataset):
123
+ validation_dataset.device = 'cpu'
124
+ data = validation_dataset.get_data()
125
+ model = GoogleActor(scale_factor=100)
126
+ scores = model(data)
127
+ return scores
128
+
google_solver/scratch.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ from just_time_windows.google_solver.google_model import evaluate_google_model
4
+ from just_time_windows.Actor.actor import Actor as NN_Actor
5
+ from just_time_windows.build_data import Raw_VRP_Data
6
+ from just_time_windows.dataloader import VRP_Dataset
7
+
8
+
9
+ dataset = VRP_Dataset(dataset_size=10, num_depots=1, num_nodes=12)
10
+
11
+ batch = dataset.get_batch(0, 10)
12
+
13
+ nn_actor = NN_Actor(model=None, num_movers=10, num_neighbors_action=1)
14
+
15
+
16
+ nn_output = nn_actor(batch)
17
+ time = nn_output['total_time']
18
+ arrival_times = nn_output['arrival_times']
19
+
20
+
21
+ output = evaluate_google_model(dataset)
22
+
23
+
24
+
25
+ print(arrival_times)
26
+ print(time.mean().item())
27
+ print(output.mean().item())