Corin1998 commited on
Commit
beb683a
·
verified ·
1 Parent(s): 647fdb0

Update services/optimizer.py

Browse files
Files changed (1) hide show
  1. services/optimizer.py +53 -12
services/optimizer.py CHANGED
@@ -1,20 +1,50 @@
1
  from __future__ import annotations
2
  from typing import List
3
- from ortools.constraint_solver import routing_enums_pb2
4
- from ortools.constraint_solver import pywrapcp
5
 
6
- # 単純TSP(開始=0,終了=0)
7
- def solver_tsp(durations: List[List[float]]) -> List[int]:
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  n = len(durations)
9
- manager = pywrapcp.RoutingIndexManager(n, 1, 0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  routing = pywrapcp.RoutingModel(manager)
11
 
12
  def time_cb(from_index, to_index):
13
  i = manager.IndexToNode(from_index)
14
  j = manager.IndexToNode(to_index)
15
- return int(durations[i][j])
16
-
17
- transit_cb_index = routing.TegisterTransitCallback(time_cb)
18
  routing.SetArcCostEvaluatorOfAllVehicles(transit_cb_index)
19
 
20
  search_params = pywrapcp.DefaultRoutingSearchParameters()
@@ -23,13 +53,24 @@ def solver_tsp(durations: List[List[float]]) -> List[int]:
23
  search_params.time_limit.FromSeconds(5)
24
 
25
  solution = routing.SolveWithParameters(search_params)
26
- if solution is None :
27
- return list(range(n))
28
-
 
 
 
 
 
 
 
 
 
 
 
29
  index = routing.Start(0)
30
  order = []
31
  while not routing.IsEnd(index):
32
  order.append(manager.IndexToNode(index))
33
  index = solution.Value(routing.NextVar(index))
34
- order.append(manager.IndexToNode(index))
35
  return order
 
1
  from __future__ import annotations
2
  from typing import List
 
 
3
 
4
+ # Try OR-Tools; fallback to a simple nearest-neighbor if unavailable
5
+ try:
6
+ from ortools.constraint_solver import routing_enums_pb2
7
+ from ortools.constraint_solver import pywrapcp
8
+ except Exception: # pragma: no cover
9
+ routing_enums_pb2 = None
10
+ pywrapcp = None
11
+
12
+
13
+ def solve_tsp(durations: List[List[float]]) -> List[int]:
14
+ """
15
+ Solve a single-vehicle TSP with start/end at node 0 on the given duration matrix (seconds).
16
+ Returns a list of node indices in visiting order, including the final 0 (start=end).
17
+ Falls back to nearest-neighbor if OR-Tools is not available.
18
+ """
19
  n = len(durations)
20
+ if n == 0:
21
+ return []
22
+ if n == 1:
23
+ return [0]
24
+
25
+ # Fallback: nearest-neighbor tour + return to start
26
+ if pywrapcp is None:
27
+ order = [0]
28
+ remaining = set(range(1, n))
29
+ cur = 0
30
+ while remaining:
31
+ nxt = min(remaining, key=lambda j: durations[cur][j])
32
+ order.append(nxt)
33
+ remaining.remove(nxt)
34
+ cur = nxt
35
+ order.append(0)
36
+ return order
37
+
38
+ # OR-Tools exact/heuristic solution
39
+ manager = pywrapcp.RoutingIndexManager(n, 1, 0) # 1 vehicle, depot=0
40
  routing = pywrapcp.RoutingModel(manager)
41
 
42
  def time_cb(from_index, to_index):
43
  i = manager.IndexToNode(from_index)
44
  j = manager.IndexToNode(to_index)
45
+ return int(max(0, durations[i][j]))
46
+
47
+ transit_cb_index = routing.RegisterTransitCallback(time_cb)
48
  routing.SetArcCostEvaluatorOfAllVehicles(transit_cb_index)
49
 
50
  search_params = pywrapcp.DefaultRoutingSearchParameters()
 
53
  search_params.time_limit.FromSeconds(5)
54
 
55
  solution = routing.SolveWithParameters(search_params)
56
+ if solution is None:
57
+ # Fallback if solver fails
58
+ order = [0]
59
+ remaining = set(range(1, n))
60
+ cur = 0
61
+ while remaining:
62
+ nxt = min(remaining, key=lambda j: durations[cur][j])
63
+ order.append(nxt)
64
+ remaining.remove(nxt)
65
+ cur = nxt
66
+ order.append(0)
67
+ return order
68
+
69
+ # Extract route
70
  index = routing.Start(0)
71
  order = []
72
  while not routing.IsEnd(index):
73
  order.append(manager.IndexToNode(index))
74
  index = solution.Value(routing.NextVar(index))
75
+ order.append(manager.IndexToNode(index)) # return to depot
76
  return order