-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmainscript_constructive.py
More file actions
145 lines (126 loc) · 4.48 KB
/
mainscript_constructive.py
File metadata and controls
145 lines (126 loc) · 4.48 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import os
import csv
from instance_parser import parse_instance
from constructive_solver import construct_initial_solution, post_merge_routes
from utils import make_routes_battery_feasible
from local_search import apply_local_search, plot_routes, route_cost
from fitness import fitness_function
import matplotlib.pyplot as plt
# === CONFIG ===
INSTANCE_DIR = "instance_files"
RESULTS_FILE = "evaluation_results.csv"
TARGET_INSTANCES = ["C101-10.xml", "R102-10.xml", "RC102-10.xml"]
penalty_weights = {
'missing_customers': 1e6,
'battery_depletion': 1e4,
'unreachable_node': 1e5,
'unnecessary_recharges': 1000,
'low_battery': 5000,
'capacity_overload': 1e5,
'max_travel_time_exceeded': 1e5,
'invalid_route': 1e5,
'vehicle_count': 1e4,
}
def save_result_to_csv(instance_name, method, fitness, battery_feasible, route_count, vehicle_count, comment=""):
file_exists = os.path.isfile(RESULTS_FILE)
with open(RESULTS_FILE, mode='a', newline='') as file:
writer = csv.writer(file)
if not file_exists:
writer.writerow(["Instance", "Method", "Fitness", "Battery Feasible", "Route Count", "Vehicle Count", "Comments"])
writer.writerow([
instance_name,
method,
f"{fitness:.2f}",
"YES" if battery_feasible else "NO",
route_count,
vehicle_count,
comment
])
# === RUN FOR EACH INSTANCE ===
for filename in TARGET_INSTANCES:
print(f"\nProcessing: {filename}")
filepath = os.path.join(INSTANCE_DIR, filename)
# === Parse ===
(nodes, charging_stations, depot, customers,
cost_matrix, travel_time_matrix, E_max, _,
vehicle_capacity, max_travel_time, requests) = parse_instance(filepath)
# Patch self-loops
for n in nodes:
cost_matrix[(n, n)] = 0
travel_time_matrix[(n, n)] = 0
# === Initial Construction ===
initial_routes = construct_initial_solution(
nodes, depot, customers, cost_matrix, vehicle_capacity,
E_max, requests, charging_stations
)
battery_routes = make_routes_battery_feasible(
initial_routes, cost_matrix, E_max, charging_stations, depot
)
battery_routes = post_merge_routes(
battery_routes, cost_matrix, vehicle_capacity, E_max,
charging_stations, depot, requests
)
# Re-fix battery feasibility
battery_routes = make_routes_battery_feasible(
battery_routes, cost_matrix, E_max, charging_stations, depot
)
# === Local Search ===
optimized_routes = apply_local_search(
battery_routes,
cost_matrix=cost_matrix,
travel_time_matrix=travel_time_matrix,
E_max=E_max,
charging_stations=charging_stations,
recharge_amount=E_max,
penalty_weights=penalty_weights,
depot=depot,
nodes=nodes,
vehicle_capacity=vehicle_capacity,
max_travel_time=max_travel_time,
requests=requests,
customers=customers
)
from evrp_utils import sanitize_routes
# Deduplicate and clean up
optimized_routes = sanitize_routes(
optimized_routes,
depot=depot,
charging_stations=charging_stations
)
# === Evaluate ===
fitness, battery_ok = fitness_function(
optimized_routes, cost_matrix, travel_time_matrix,
E_max, charging_stations, E_max, penalty_weights,
depot, nodes, vehicle_capacity, max_travel_time,
requests, customers
)
print(f"\nFinal Evaluation for {filename}:")
print(f" Total Routes: {len(optimized_routes)}")
print(f" Fitness Score: {fitness}")
print(f" Battery Feasible: {'YES' if battery_ok else 'NO'}")
for i, route in enumerate(optimized_routes):
print(f" Route {i+1}: {route} (Cost: {route_cost(route, cost_matrix)})")
# Use filename as instance_id
instance_id = filename.replace(".xml", "")
plot_routes(
optimized_routes,
nodes=nodes,
depot=depot,
charging_stations=charging_stations,
cost_matrix=cost_matrix,
E_max=E_max,
save_plot=False,
method="CWS",
instance_id=instance_id
)
# Ensure plot stays open until manually closed
plt.show(block=True)
save_result_to_csv(
instance_name=filename,
method="CWS",
fitness=fitness,
battery_feasible=battery_ok,
route_count=len(optimized_routes),
vehicle_count=len(optimized_routes),
comment="CWS result from mainscript_constructive.py"
)