Skip to content

Commit 09492dd

Browse files
committed
bugfix
1 parent 48ae9e3 commit 09492dd

File tree

4 files changed

+79
-18
lines changed

4 files changed

+79
-18
lines changed

src/DynamicVehicleScheduling/anticipative_solver.jl

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ function anticipative_solver(
5151
nb_epochs=typemax(Int),
5252
seed=get_seed(env),
5353
)
54-
reset_env && reset!(env; reset_rng=true, seed)
54+
if reset_env
55+
reset!(env; reset_rng=true, seed)
56+
end
5557

5658
start_epoch = current_epoch(env)
5759
end_epoch = min(last_epoch(env), start_epoch + nb_epochs - 1)
5860
T = start_epoch:end_epoch
59-
@info T
6061

6162
request_epoch = [0]
6263
for t in T
@@ -70,7 +71,7 @@ function anticipative_solver(
7071
(; epoch_duration, Δ_dispatch) = env.instance
7172

7273
model = model_builder()
73-
# set_silent(model)
74+
set_silent(model)
7475

7576
nb_nodes = length(customer_index)
7677
job_indices = 2:nb_nodes
@@ -129,11 +130,44 @@ function anticipative_solver(
129130

130131
optimize!(model)
131132

132-
@info "Objective value: $(JuMP.objective_value(model))"
133-
@info termination_status(model)
134-
y_val = value.(y)
135-
@info sum(y_val[j, 2, t] for j in 1:nb_nodes, t in epoch_indices)
136-
133+
# Debug infeasibility
134+
if termination_status(model) == JuMP.MOI.INFEASIBLE
135+
@warn "Model is infeasible! Let's debug..."
136+
@info "Number of nodes: $nb_nodes"
137+
@info "Number of job indices: $(length(job_indices))"
138+
@info "Epoch indices: $epoch_indices"
139+
@info "Request epochs: $request_epoch"
140+
@info "Start times: $start_time"
141+
@info "Service times: $service_time"
142+
@info "Epoch duration: $epoch_duration, Δ_dispatch: $Δ_dispatch"
143+
144+
# Check if any job can be scheduled in any epoch
145+
for i in job_indices
146+
can_schedule = false
147+
for t in epoch_indices
148+
# Check release constraint
149+
if t >= request_epoch[i]
150+
# Check time limit constraint
151+
travel_time = duration[1, i]
152+
arrival_time = (t - 1) * epoch_duration + Δ_dispatch + travel_time
153+
if arrival_time <= start_time[i]
154+
can_schedule = true
155+
@info "Job $i can be scheduled in epoch $t (arrival: $arrival_time <= deadline: $(start_time[i]))"
156+
break
157+
else
158+
@info "Job $i cannot be scheduled in epoch $t: arrival $arrival_time > deadline $(start_time[i])"
159+
end
160+
else
161+
@info "Job $i cannot be scheduled in epoch $t: request epoch $(request_epoch[i]) > epoch $t"
162+
end
163+
end
164+
if !can_schedule
165+
@warn "Job $i cannot be scheduled in any epoch! Request epoch: $(request_epoch[i]), start time: $(start_time[i]), travel time: $(duration[1, i]), release index $(customer_index[i])"
166+
@warn " Epochs available: $epoch_indices"
167+
@warn " Epoch duration: $epoch_duration, Δ_dispatch: $Δ_dispatch"
168+
end
169+
end
170+
end
137171
obj = JuMP.objective_value(model)
138172
epoch_routes = retrieve_routes_anticipative(
139173
value.(y), env, customer_index, epoch_indices

src/DynamicVehicleScheduling/instance.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function Instance(
3131
maximum(static_instance.start_time) - minimum(static_instance.duration[1, :]) -
3232
Δ_dispatch
3333
) / epoch_duration,
34-
)
34+
) - 1
3535
return Instance(;
3636
static_instance=static_instance,
3737
max_requests_per_epoch=max_requests_per_epoch,

src/DynamicVehicleScheduling/plot.jl

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -476,11 +476,38 @@ function animate_epochs(
476476
(0.0, 1.0)
477477
end
478478

479-
# Create animation with alternating state and route frames
480-
anim = @animate for frame_idx in 1:(2*n_epochs)
481-
epoch_idx = ceil(Int, frame_idx / 2)
482-
is_route_frame = (frame_idx % 2 == 0)
479+
# Helper function to check if routes exist and are non-empty
480+
function has_routes(routes)
481+
if isnothing(routes)
482+
return false
483+
elseif routes isa Vector{Vector{Int}}
484+
return any(!isempty(route) for route in routes)
485+
elseif routes isa Vector{Int}
486+
return !isempty(routes)
487+
elseif routes isa BitMatrix
488+
return any(routes)
489+
else
490+
return false
491+
end
492+
end
483493

494+
# Create frame plan: determine which epochs have routes
495+
frame_plan = []
496+
for (epoch_idx, sample) in enumerate(data_samples)
497+
# Always add state frame
498+
push!(frame_plan, (epoch_idx, :state))
499+
500+
# Add routes frame only if routes exist
501+
if has_routes(sample.y_true)
502+
push!(frame_plan, (epoch_idx, :routes))
503+
end
504+
end
505+
506+
total_frames = length(frame_plan)
507+
508+
# Create animation with dynamic frame plan
509+
anim = @animate for frame_idx in 1:total_frames
510+
epoch_idx, frame_type = frame_plan[frame_idx]
484511
sample = data_samples[epoch_idx]
485512
state = sample.instance
486513

@@ -498,7 +525,7 @@ function animate_epochs(
498525
kwargs...
499526
)
500527
else
501-
if is_route_frame && !isnothing(sample.y_true)
528+
if frame_type == :routes
502529
# Show state with routes
503530
plot_routes(state, sample.y_true;
504531
xlims=xlims,
@@ -514,7 +541,7 @@ function animate_epochs(
514541
show_route_labels=false,
515542
size=figsize,
516543
kwargs...)
517-
else
544+
else # frame_type == :state
518545
# Show state only
519546
plot_state(state;
520547
xlims=xlims,

test/dynamic_assortment.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ end
272272
b = DynamicAssortmentBenchmark(N=5, d=2, K=3, max_steps=20)
273273

274274
# Generate test data
275-
dataset = generate_dataset(b, 5; seed=0)
275+
dataset = generate_dataset(b, 10; seed=0)
276276
environments = generate_environments(b, dataset)
277277

278278
# Get policies
@@ -284,8 +284,8 @@ end
284284
@test greedy.name == "Greedy"
285285

286286
# Test policy evaluation
287-
r_expert, d = evaluate_policy!(expert, environments)
288-
r_greedy, _ = evaluate_policy!(greedy, environments)
287+
r_expert, d = evaluate_policy!(expert, environments, 10)
288+
r_greedy, _ = evaluate_policy!(greedy, environments, 10)
289289

290290
@test length(r_expert) == length(environments)
291291
@test length(r_greedy) == length(environments)

0 commit comments

Comments
 (0)