cost-matrix 0.1.1__py3-none-any.whl → 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cost_matrix/osrm_matrix.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import os
|
2
|
+
from concurrent.futures import ThreadPoolExecutor
|
1
3
|
from math import ceil
|
2
4
|
|
3
5
|
import numpy as np
|
@@ -33,54 +35,66 @@ def osrm(
|
|
33
35
|
np.ndarray
|
34
36
|
OSRM cost matrix of shape (n, m).
|
35
37
|
"""
|
36
|
-
|
37
38
|
num_sources = sources.shape[0]
|
38
39
|
num_destinations = destinations.shape[0]
|
39
|
-
cost_matrix = np.zeros((num_sources, num_destinations))
|
40
|
+
cost_matrix = np.zeros((num_sources, num_destinations), dtype=np.float32)
|
40
41
|
|
41
42
|
num_batches_i = ceil(num_sources / batch_size)
|
42
43
|
num_batches_j = ceil(num_destinations / batch_size)
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
cpu_count = os.cpu_count() or 0
|
46
|
+
default_max = cpu_count * 2 if cpu_count > 0 else 8
|
47
|
+
max_workers = min(default_max, 16)
|
48
|
+
|
49
|
+
futures = []
|
50
|
+
positions = []
|
51
|
+
|
52
|
+
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
53
|
+
for i in range(num_batches_i):
|
54
|
+
start_i = i * batch_size
|
55
|
+
end_i = min((i + 1) * batch_size, num_sources)
|
47
56
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
sources_batch = sources[start_i:end_i]
|
52
|
-
destinations_batch = destinations[start_j:end_j]
|
57
|
+
for j in range(num_batches_j):
|
58
|
+
start_j = j * batch_size
|
59
|
+
end_j = min((j + 1) * batch_size, num_destinations)
|
53
60
|
|
54
|
-
|
55
|
-
|
61
|
+
sources_batch = sources[start_i:end_i]
|
62
|
+
destinations_batch = destinations[start_j:end_j]
|
63
|
+
|
64
|
+
future = executor.submit(
|
65
|
+
_fetch_matrix_batch,
|
56
66
|
sources_batch,
|
57
67
|
destinations_batch,
|
58
68
|
server_address,
|
59
|
-
cost_type
|
69
|
+
cost_type,
|
60
70
|
)
|
61
|
-
|
71
|
+
futures.append(future)
|
72
|
+
positions.append((start_i, end_i, start_j, end_j))
|
73
|
+
|
74
|
+
for future, (start_i, end_i, start_j, end_j) in zip(
|
75
|
+
futures, positions, strict=False
|
76
|
+
):
|
77
|
+
cost_matrix[start_i:end_i, start_j:end_j] = future.result()
|
62
78
|
|
63
79
|
return cost_matrix
|
64
80
|
|
65
81
|
|
66
|
-
def
|
82
|
+
def _fetch_matrix_batch(
|
67
83
|
sources_batch: np.ndarray,
|
68
84
|
destinations_batch: np.ndarray,
|
69
85
|
server_address: str,
|
70
86
|
cost_type: str,
|
71
87
|
):
|
72
88
|
"""Request the OSRM cost matrix for a given batch"""
|
73
|
-
|
74
|
-
url = _format_osrm_url(
|
89
|
+
url = _format_url(
|
75
90
|
sources_batch, destinations_batch, server_address, cost_type
|
76
91
|
)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
return np.array(resp.json()[cost_type])
|
92
|
+
response = requests.get(url)
|
93
|
+
response.raise_for_status()
|
94
|
+
return np.array(response.json()[cost_type], dtype=np.float32)
|
81
95
|
|
82
96
|
|
83
|
-
def
|
97
|
+
def _format_url(
|
84
98
|
sources_batch: np.ndarray,
|
85
99
|
destinations_batch: np.ndarray,
|
86
100
|
server_address: str,
|
@@ -114,11 +128,8 @@ def _format_osrm_url(
|
|
114
128
|
"distance"), but the returned JSON follows the plural form (e.g.,
|
115
129
|
"distances"). Thus, we ignore the last letter of the input type
|
116
130
|
"""
|
117
|
-
|
118
131
|
url_cost_type = cost_type[:-1]
|
119
|
-
sources_coord = ";".join(
|
120
|
-
f"{source[1]},{source[0]}" for source in sources_batch
|
121
|
-
)
|
132
|
+
sources_coord = ";".join(f"{lng},{lat}" for (lat, lng) in sources_batch)
|
122
133
|
|
123
134
|
# If sources == destinations, return a simpler URL early. Notice it needs
|
124
135
|
# at least two points, otherwise OSRM complains
|
@@ -127,14 +138,12 @@ def _format_osrm_url(
|
|
127
138
|
and sources_batch.shape[0] > 1
|
128
139
|
):
|
129
140
|
return (
|
130
|
-
f"{server_address}/table/v1/driving/"
|
131
|
-
f"{sources_coord}"
|
141
|
+
f"{server_address}/table/v1/driving/{sources_coord}"
|
132
142
|
f"?annotations={url_cost_type}"
|
133
143
|
)
|
134
144
|
|
135
145
|
destinations_coord = ";".join(
|
136
|
-
f"{
|
137
|
-
for destination in destinations_batch
|
146
|
+
f"{lng},{lat}" for (lat, lng) in destinations_batch
|
138
147
|
)
|
139
148
|
locations_coord = sources_coord + ";" + destinations_coord
|
140
149
|
|
@@ -142,7 +151,6 @@ def _format_osrm_url(
|
|
142
151
|
# sources = 0,1,...,N' and destinations = N'+1,N'+2...N'+M'
|
143
152
|
num_sources = sources_batch.shape[0]
|
144
153
|
num_destinations = destinations_batch.shape[0]
|
145
|
-
|
146
154
|
sources_indices = ";".join(str(index) for index in range(num_sources))
|
147
155
|
destinations_indices = ";".join(
|
148
156
|
str(index)
|
@@ -150,8 +158,8 @@ def _format_osrm_url(
|
|
150
158
|
)
|
151
159
|
|
152
160
|
return (
|
153
|
-
f"{server_address}/table/v1/driving/"
|
154
|
-
f"{
|
155
|
-
f"
|
161
|
+
f"{server_address}/table/v1/driving/{locations_coord}"
|
162
|
+
f"?sources={sources_indices}"
|
163
|
+
f"&destinations={destinations_indices}"
|
156
164
|
f"&annotations={url_cost_type}"
|
157
165
|
)
|
@@ -1,12 +1,11 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.3
|
2
2
|
Name: cost-matrix
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.2.0
|
4
4
|
Summary: Designed to simplify the creation of cost matrices for optimization problems.
|
5
5
|
Author: Luan
|
6
6
|
Author-email: llvdmoraes@gmail.com
|
7
|
-
Requires-Python: >=3.
|
7
|
+
Requires-Python: >=3.10,<3.13
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
9
|
-
Classifier: Programming Language :: Python :: 3.9
|
10
9
|
Classifier: Programming Language :: Python :: 3.10
|
11
10
|
Classifier: Programming Language :: Python :: 3.11
|
12
11
|
Classifier: Programming Language :: Python :: 3.12
|
@@ -71,3 +70,6 @@ osrm_duration_matrix = cost_matrix.osrm(
|
|
71
70
|
print(osrm_duration_matrix)
|
72
71
|
```
|
73
72
|
|
73
|
+
## GitHub
|
74
|
+
* [Repository](https://github.com/luanleonardo/cost-matrix)
|
75
|
+
|
@@ -1,8 +1,8 @@
|
|
1
1
|
cost_matrix/__init__.py,sha256=9EaPsXe0SIuym34-CPmzUPSGJuBd2AkQZHqjcwlUywE,202
|
2
2
|
cost_matrix/euclidean_matrix.py,sha256=PiOJFjalkvk1p4ktcCvFD7EeXswvsnm8f-oze1gFRlk,844
|
3
3
|
cost_matrix/manhattan_matrix.py,sha256=OgOepYRfskarZmNNarl58YqNRw7WXYnjztWV2BbjGBI,907
|
4
|
-
cost_matrix/osrm_matrix.py,sha256=
|
4
|
+
cost_matrix/osrm_matrix.py,sha256=mlj61VoMKb0hisDl4xdNa_-9gw0RgtILmr4GpjIFg3k,5495
|
5
5
|
cost_matrix/spherical_matrix.py,sha256=9_y5XCpdAEiWcvljPX7kFYSUt0nU3Gq4DOwr7LlbhQY,1271
|
6
|
-
cost_matrix-0.
|
7
|
-
cost_matrix-0.
|
8
|
-
cost_matrix-0.
|
6
|
+
cost_matrix-0.2.0.dist-info/METADATA,sha256=IZyDlKzSf0C4bnMICS8CgmO6Lrb95eXlXNkK0wVC1is,2702
|
7
|
+
cost_matrix-0.2.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
8
|
+
cost_matrix-0.2.0.dist-info/RECORD,,
|