Skip to content

Commit

Permalink
Fixes issue with nil mix items in mixing constraint (#60)
Browse files Browse the repository at this point in the history
* Fixes issue where constraint returns a violation for a stop without mix items

* Rename testcase

* Simplify mixing items constraint, fix mixing items output report, add missing/null mixing item test case

* Ignore some files for testing

* Upgrade SDK to 1.6.3

---------

Co-authored-by: Marius Merschformann <marius.merschformann@gmail.com>
  • Loading branch information
nmisek and merschformann authored Aug 6, 2024
1 parent 5221220 commit 959f78c
Show file tree
Hide file tree
Showing 12 changed files with 423 additions and 12 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.html
*.png
4 changes: 4 additions & 0 deletions cmd/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
cmd
main
*.json
*.sh
*.yaml
*.yml
16 changes: 7 additions & 9 deletions factory/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,15 @@ func toPlannedStopOutput(solutionStop nextroute.SolutionStop) schema.PlannedStop
int(math.Max(arrival.Sub(*inputStop.TargetArrivalTime).Seconds(), 0.0))
}

if inputStop.MixingItems != nil {
mixItems := make(map[string]nextroute.MixItem)
for _, constraint := range solutionStop.Vehicle().ModelVehicle().Model().Constraints() {
if noMixConstraint, ok := constraint.(nextroute.NoMixConstraint); ok {
mixItems[strings.TrimPrefix(noMixConstraint.ID(), "no_mix_")] = noMixConstraint.Value(solutionStop)
}
}
if len(mixItems) > 0 {
plannedStopOutput.MixItems = mixItems
mixItems := make(map[string]nextroute.MixItem)
for _, constraint := range solutionStop.Vehicle().ModelVehicle().Model().Constraints() {
if noMixConstraint, ok := constraint.(nextroute.NoMixConstraint); ok {
mixItems[strings.TrimPrefix(noMixConstraint.ID(), "no_mix_")] = noMixConstraint.Value(solutionStop)
}
}
if len(mixItems) > 0 {
plannedStopOutput.MixItems = mixItems
}
}

hasTravelDistance := solutionStop.Previous().ModelStop().Location().IsValid() &&
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/nextmv-io/nextroute
go 1.21

require (
github.com/nextmv-io/sdk v1.6.0
github.com/nextmv-io/sdk v1.6.3
gonum.org/v1/gonum v0.14.0
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nextmv-io/sdk v1.6.0 h1:WU9/znVN9XzXNUXWoQu9t6xZCHZ4AOaKBi4yqFVLLG0=
github.com/nextmv-io/sdk v1.6.0/go.mod h1:4kKTivuXdlx2ky+ZkBeUkTPIc8BTJ0PqKFYF3B+wCy4=
github.com/nextmv-io/sdk v1.6.3 h1:Jtqxmn8FTvhRM1kIyaukB6k/2ekXBI8+h8acEZpPMLs=
github.com/nextmv-io/sdk v1.6.3/go.mod h1:Y48XLPcIOOxRgO86ICNpqGrH2N5+dd1TDNvef/FD2Kc=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
Expand Down
8 changes: 8 additions & 0 deletions model_constraint_no_mix.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,14 @@ func (l *noMixConstraintImpl) EstimateIsViolated(
deltaQuantity += insertMixItem.Quantity
}

if !hasRemoveMixItem && !hasInsertMixItem {
// If the stop is not associated with any mix item, then the constraint
// cannot be violated (as it is not mixing any new item between existing
// ones). Note that the content name of all stops of a move is the same,
// so it is enough to check the first stop.
return false, constNoPositionsHint
}

tour := previousNoMixData.tour

if previousNoMixData.content.Quantity == 0 {
Expand Down
6 changes: 6 additions & 0 deletions tests/golden/testdata/no_mix.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@
{
"cumulative_travel_distance": 18249,
"cumulative_travel_duration": 912,
"mix_items": {
"hazchem": {
"name": "",
"quantity": 0
}
},
"stop": {
"id": "Arashiyama Bamboo Forest",
"location": {
Expand Down
96 changes: 96 additions & 0 deletions tests/golden/testdata/no_mix_null.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
{
"stops": [
{
"id": "north",
"location": {
"lon": 7.6256,
"lat": 51.9714
},
"precedes": "south",
"mixing_items": {
"main": {
"name": "A",
"quantity": 1
}
}
},
{
"id": "south",
"location": {
"lon": 7.6256,
"lat": 51.9534
},
"precedes": "south_west",
"mixing_items": {
"main": {
"name": "A",
"quantity": -1
}
}
},
{
"id": "east",
"location": {
"lon": 7.6402,
"lat": 51.9624
},
"precedes": "west",
"mixing_items": {
"main": {
"name": "B",
"quantity": 1
}
}
},
{
"id": "west",
"location": {
"lon": 7.611,
"lat": 51.9624
},
"precedes": "north_west",
"mixing_items": {
"main": {
"name": "B",
"quantity": -1
}
}
},
{
"id": "north_east",
"location": {
"lon": 7.6359,
"lat": 51.9688
},
"mixing_items": null
},
{
"id": "south_east",
"location": {
"lon": 7.6359,
"lat": 51.956
},
"mixing_items": null
},
{
"id": "south_west",
"location": {
"lon": 7.6153,
"lat": 51.956
}
},
{
"id": "north_west",
"location": {
"lon": 7.6153,
"lat": 51.9688
}
}
],
"vehicles": [
{
"id": "truck",
"speed": 20
}
]
}
Loading

0 comments on commit 959f78c

Please sign in to comment.