-
Notifications
You must be signed in to change notification settings - Fork 2
Perturbation
markkvdb edited this page Mar 10, 2017
·
2 revisions
Three destroy operators (remove q customers) + 1 repair operator (reinserts customers).
- Select seed customer from customer list. Store in toBeRemoved.
- Find q-1 nearest customers. Store in toBeRemoved.
- removeCustomers(solution, toBeRemoved) (see below)
- For each customer in toBeRemoved:
- For each vehicle of customer:
- Find place customer in route
- Remove customer from route (and dropoff)
- Update load, length, serviceTime, route cost
- Remove depot+vehicle_id from customer
- For each vehicle of customer:
- toBeReinserted = toBeRemoved (for later use)
- Return destroyed solution and toBeReinserted
- For customers 1,...,n:
- computeRemovalGain(solution, customer) (see below)
- store result in vector gains, along with customer_id (gains = 1,gain_1],...,[n,gain_n)
- Find q largest gains, store corresponding customer_ids in toBeRemoved
- removeCustomers(solution, toBeRemoved)
- For each vehicle of customer, compute vehicleRemovalGain:
- Find place in route
- Distance gain: Use distanceMatrix (multiply by alpha)
- Feasibility gain (only if route is infeasible in the first place):
- Find old and new travel duration (travel time + service time)
- Use arithmetic.
- vehicleRemovalGain = distance gain + feasibility gain
- totalRemovalGain = sum(vehicleRemovalGain)
- totalRemovalGain = totalRemovalGain * uniform(a, b) (a = 0.8, b = 1.2)(RNG).
- return totalRemovalGain
- Pick random non-empty vehicle.
- Find corresponding route
- Store at random min(q, route.length()) customers in toBeRemoved
- removeCustomers(solution, toBeRemoved)
- demand = demand(toBeReinserted)
- While toBeReinserted is not empty
- Select random customer from toBeReinserted.
- minInsertion = Infinity
- depot = -1, vehicle = -1, idx = -1 (initilize insertion location)
- For each vehicle
- For each insertion option
- Find insertionCost:
- Additional travel costs
- Infeasibility penalties
- If (insertion costs < minInsertion)
- minInsertion = insertionCost
- update: depot, vehicle, and idx
- Find insertionCost:
- For each insertion option
- Insert customer at depot, vehicle, idx:
- If (insufficient inventory/capacity)
- Allocate as much as possible and split demand
- Update demand
- If (sufficient inventory and capacity)
- Allocate all demand
- remove customer from toBeReinserted
- Return solution Note: we can alternatively check in advance for sufficient inventory/capacity, and discard the insertion option if insufficient. One problem is that all insertion options may be discarded (a simple workaround is to repeat the search, now allowing for splits). I suggest moving this to the tuning phase (if it turns out that too many splits are generated, this is one place where we can look.)