-
Notifications
You must be signed in to change notification settings - Fork 4
/
model_objective_min_stops.go
73 lines (61 loc) · 2.16 KB
/
model_objective_min_stops.go
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
// © 2019-present nextmv.io inc
package nextroute
// NewMinStopsObjective returns a new MinStopsObjective.
func NewMinStopsObjective(minStops, minStopsPenalty VehicleTypeExpression) ModelObjective {
return &minStopsObjectiveImpl{
minStops: minStops,
minStopsPenalty: minStopsPenalty,
}
}
type minStopsObjectiveImpl struct {
minStops VehicleTypeExpression
minStopsPenalty VehicleTypeExpression
}
func (t *minStopsObjectiveImpl) EstimateDeltaValue(move SolutionMoveStops) float64 {
moveImpl := move.(*solutionMoveStopsImpl)
vehicle := moveImpl.vehicle()
modelVehicle := vehicle.ModelVehicle().(*modelVehicleImpl)
minimum := int(t.minStops.ValueForVehicleType(modelVehicle.vehicleType))
vehicleStops := vehicle.NumberOfStops()
if vehicleStops >= minimum {
return 0
}
moveStops := len(moveImpl.stopPositions)
if vehicle.IsEmpty() {
if moveStops >= minimum {
return 0
}
return t.minStopsPenalty.ValueForVehicleType(modelVehicle.vehicleType) *
(float64(minimum) - float64(moveStops)) *
(float64(minimum) - float64(moveStops))
}
oldDelta := minimum - vehicleStops
newDelta := minimum - vehicleStops - moveStops
if newDelta >= 0 {
return t.minStopsPenalty.ValueForVehicleType(modelVehicle.vehicleType) *
(float64(newDelta)*float64(newDelta) - float64(oldDelta)*float64(oldDelta))
}
return t.minStopsPenalty.ValueForVehicleType(modelVehicle.vehicleType) *
-float64(oldDelta) * float64(oldDelta)
}
func (t *minStopsObjectiveImpl) Value(solution Solution) float64 {
solutionImpl := solution.(*solutionImpl)
penaltySum := 0.0
for _, vehicle := range solutionImpl.vehicles {
vehicleNumberOfStops := vehicle.NumberOfStops()
if vehicleNumberOfStops == 0 {
continue
}
modelVehicle := vehicle.ModelVehicle().(*modelVehicleImpl)
minimum := int(t.minStops.ValueForVehicleType(modelVehicle.vehicleType))
if vehicleNumberOfStops < minimum {
penaltySum += t.minStopsPenalty.ValueForVehicleType(modelVehicle.vehicleType) *
(float64(minimum) - float64(vehicleNumberOfStops)) *
(float64(minimum) - float64(vehicleNumberOfStops))
}
}
return penaltySum
}
func (t *minStopsObjectiveImpl) String() string {
return "min_stops"
}