From 05610411b10f3d4f097ec534011acbbe4a9a766b Mon Sep 17 00:00:00 2001 From: Marius Merschformann Date: Thu, 6 Nov 2025 14:38:13 +0100 Subject: [PATCH 1/2] Avoiding unplanning of units units for vehicle and island heuristics --- solve_operator_unplan.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/solve_operator_unplan.go b/solve_operator_unplan.go index e23836fa..b09718c7 100644 --- a/solve_operator_unplan.go +++ b/solve_operator_unplan.go @@ -168,6 +168,12 @@ func (d *solveOperatorUnPlanImpl) unplanOneIsland( numberOfStops int, ) (int, error) { planUnit := solution.PlannedPlanUnits().RandomElement() + + // Reject island unplanning if it's a units-unit. + if isUnitsUnit(planUnit) { + return 0, nil + } + planStopsUnit := common.RandomElement(solution.Random(), planUnit.PlannedPlanStopsUnits()) for _, solutionStop := range planStopsUnit.(*solutionPlanStopsUnitImpl).solutionStops { return d.unplanOneStopIsland( @@ -222,10 +228,23 @@ func (d *solveOperatorUnPlanImpl) unplanSomeStopsOfOneVehicle( for _, stop := range stops { if stop.IsPlanned() && !stop.IsFixed() { + // TODO: should this be inverted (our chance is 0.2, so 80% chance + // to unplan - a.k.a. NOT skip unplanning)? if solution.Random().Float64() < chance { continue } - unplanned, err := stop.PlanStopsUnit().UnPlan() + + planStopsUnit := stop.PlanStopsUnit() + + // // Get parent of unit to unplan full units. + // planStopsUnit := solution.PlannedPlanUnits().SolutionPlanUnit(stop.modelStop().planUnit) + + // Reject unplanning if it's a units-unit. + if isUnitsUnit(planStopsUnit) { + continue + } + + unplanned, err := planStopsUnit.UnPlan() if err != nil { return 0, err } From ba03513f6754d4b2b778341b647b596598000620 Mon Sep 17 00:00:00 2001 From: Marius Merschformann Date: Thu, 6 Nov 2025 14:42:31 +0100 Subject: [PATCH 2/2] Adding type check helper func --- solve_operator_unplan.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/solve_operator_unplan.go b/solve_operator_unplan.go index b09718c7..136f5e56 100644 --- a/solve_operator_unplan.go +++ b/solve_operator_unplan.go @@ -290,3 +290,13 @@ func (d *solveOperatorUnPlanImpl) unplanLocation( return count, nil } + +func isUnitsUnit(plannedPlanUnit SolutionPlanUnit) bool { + switch plannedPlanUnit.(type) { + case SolutionPlanStopsUnit: + return false + case SolutionPlanUnitsUnit: + return true + } + panic("unknown solution plan unit type") +}