Skip to content

Commit

Permalink
Reduce allocations when generating sequences
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkschumacher committed May 20, 2024
1 parent fe8392c commit 13fad8b
Show file tree
Hide file tree
Showing 3 changed files with 354 additions and 333 deletions.
32 changes: 20 additions & 12 deletions solution_sequence_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ func SequenceGeneratorChannel(
for _, arc := range dag.arcs {
inDegree[arc.Destination().Index()]++
}

random := solution.Random()
sequenceGenerator(
solutionStops,
make([]SolutionStop, 0, len(solutionStops)),
random.Perm(len(solutionStops)),
used,
inDegree,
dag,
solution.Random(),
random,
&maxSequences,
func(solutionStops SolutionStops) {
select {
Expand All @@ -77,6 +78,7 @@ func SequenceGeneratorChannel(

func sequenceGenerator(
stops, sequence SolutionStops,
stopOrder []int,
used []bool,
inDegree map[int]int,
dag DirectedAcyclicGraph,
Expand All @@ -91,23 +93,23 @@ func sequenceGenerator(
}
return
}

stopOrder := random.Perm(len(stops))
localStopOrder := stopOrder

// we know the direct successor, so we move it to the front of the random
// sequence
if directSuccessor != -1 {
isDirectSuccessor := directSuccessor != -1
if isDirectSuccessor {
for _, stopIdx := range stopOrder {
if stops[stopIdx].Index() == directSuccessor {
stopOrder = []int{stopIdx}
localStopOrder = stopOrder[:1]
localStopOrder[0] = stopIdx
break
}
}
}
isDirectSuccessor := directSuccessor != -1
directSuccessor = -1

for _, idx := range stopOrder {
for _, idx := range localStopOrder {
stop := stops[idx]
if !used[idx] && inDegree[stop.ModelStop().Index()] == 0 {
used[idx] = true
Expand All @@ -119,16 +121,15 @@ func sequenceGenerator(
directSuccessor = stop.Solution().SolutionStop(arc.Destination()).Index()
}
} else {
outboundArcOrder := random.Perm(len(outboundArcs))
for _, arcsIdx := range outboundArcOrder {
arc := outboundArcs[arcsIdx]
shuffleInPlace(random, outboundArcs)
for _, arc := range outboundArcs {
inDegree[arc.Destination().Index()]--
if dag.HasDirectArc(arc.Origin(), arc.Destination()) {
directSuccessor = stop.Solution().SolutionStop(arc.Destination()).Index()
}
}
}
sequenceGenerator(stops, append(sequence, stop), used, inDegree, dag, random, maxSequences, yield, directSuccessor)
sequenceGenerator(stops, append(sequence, stop), stopOrder, used, inDegree, dag, random, maxSequences, yield, directSuccessor)
// reached the maximum number of sequences
if *maxSequences == 0 {
return
Expand All @@ -143,3 +144,10 @@ func sequenceGenerator(
}
}
}

func shuffleInPlace[T any](r *rand.Rand, slice []T) {
for i := len(slice) - 1; i > 0; i-- {
j := r.Intn(i + 1)
slice[i], slice[j] = slice[j], slice[i]
}
}
173 changes: 87 additions & 86 deletions tests/golden/testdata/precedence pathologic.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,18 @@
"name": "1 * vehicles_duration + 1 * unplanned_penalty",
"objectives": [
{
"base": 1841.9036093736736,
"base": 2205.7639215043205,
"factor": 1,
"name": "vehicles_duration",
"value": 1841.9036093736736
"value": 2205.7639215043205
},
{
"factor": 1,
"name": "unplanned_penalty",
"value": 0
}
],
"value": 1841.9036093736736
"value": 2205.7639215043205
},
"unplanned": [],
"vehicles": [
Expand All @@ -96,157 +96,158 @@
{
"cumulative_travel_duration": 0,
"stop": {
"id": "Fushimi Inari Taisha",
"id": "Arashiyama Bamboo Forest Copy",
"location": {
"lat": 34.967146,
"lon": 135.772695
"lat": 35.017209,
"lon": 135.672008
}
},
"travel_duration": 0
},
{
"cumulative_travel_distance": 3935,
"cumulative_travel_duration": 196,
"cumulative_travel_duration": 0,
"stop": {
"id": "Gionmachi",
"id": "Arashiyama Bamboo Forest",
"location": {
"lat": 35.002457,
"lon": 135.775682
"lat": 35.017209,
"lon": 135.672009
}
},
"travel_distance": 3935,
"travel_duration": 196
"travel_duration": 0
},
{
"cumulative_travel_distance": 6765,
"cumulative_travel_duration": 338,
"cumulative_travel_distance": 9583,
"cumulative_travel_duration": 479,
"stop": {
"id": "Nijō Castle Copy",
"id": "Gionmachi Copy",
"location": {
"lat": 35.014239,
"lon": 135.748135
"lat": 35.002457,
"lon": 135.775683
}
},
"travel_distance": 2830,
"travel_duration": 141
"travel_distance": 9583,
"travel_duration": 479
},
{
"cumulative_travel_distance": 8541,
"cumulative_travel_duration": 427,
"cumulative_travel_distance": 15524,
"cumulative_travel_duration": 776,
"stop": {
"id": "Kyoto Imperial Palace",
"id": "Kinkaku-ji Copy",
"location": {
"lat": 35.025431,
"lon": 135.762057
"lat": 35.039705,
"lon": 135.728899
}
},
"travel_distance": 1776,
"travel_duration": 88
"travel_distance": 5941,
"travel_duration": 297
},
{
"cumulative_travel_distance": 8541,
"cumulative_travel_duration": 427,
"cumulative_travel_distance": 18934,
"cumulative_travel_duration": 946,
"stop": {
"id": "Kyoto Imperial Palace Copy",
"id": "Kyoto Imperial Palace",
"location": {
"lat": 35.025431,
"lon": 135.762058
"lon": 135.762057
}
},
"travel_duration": 0
"travel_distance": 3410,
"travel_duration": 170
},
{
"cumulative_travel_distance": 11951,
"cumulative_travel_duration": 597,
"cumulative_travel_distance": 20710,
"cumulative_travel_duration": 1035,
"stop": {
"id": "Kinkaku-ji",
"id": "Nijō Castle",
"location": {
"lat": 35.039705,
"lon": 135.728898
"lat": 35.014239,
"lon": 135.748134
}
},
"travel_distance": 3410,
"travel_duration": 170
"travel_distance": 1776,
"travel_duration": 88
},
{
"cumulative_travel_distance": 11951,
"cumulative_travel_duration": 597,
"cumulative_travel_distance": 24039,
"cumulative_travel_duration": 1202,
"stop": {
"id": "Kinkaku-ji Copy",
"id": "Kinkaku-ji",
"location": {
"lat": 35.039705,
"lon": 135.728899
"lon": 135.728898
}
},
"travel_duration": 0
"travel_distance": 3329,
"travel_duration": 166
},
{
"cumulative_travel_distance": 15280,
"cumulative_travel_duration": 764,
"cumulative_travel_distance": 27449,
"cumulative_travel_duration": 1372,
"stop": {
"id": "Nijō Castle",
"id": "Kyoto Imperial Palace Copy",
"location": {
"lat": 35.014239,
"lon": 135.748134
"lat": 35.025431,
"lon": 135.762058
}
},
"travel_distance": 3329,
"travel_duration": 166
"travel_distance": 3410,
"travel_duration": 170
},
{
"cumulative_travel_distance": 22220,
"cumulative_travel_duration": 1111,
"cumulative_travel_distance": 29225,
"cumulative_travel_duration": 1461,
"stop": {
"id": "Arashiyama Bamboo Forest",
"id": "Nijō Castle Copy",
"location": {
"lat": 35.017209,
"lon": 135.672009
"lat": 35.014239,
"lon": 135.748135
}
},
"travel_distance": 6940,
"travel_duration": 347
"travel_distance": 1776,
"travel_duration": 88
},
{
"cumulative_travel_distance": 22220,
"cumulative_travel_duration": 1111,
"cumulative_travel_distance": 34805,
"cumulative_travel_duration": 1740,
"stop": {
"id": "Arashiyama Bamboo Forest Copy",
"id": "Fushimi Inari Taisha Copy",
"location": {
"lat": 35.017209,
"lon": 135.672008
"lat": 34.967146,
"lon": 135.72696
}
},
"travel_duration": 0
"travel_distance": 5580,
"travel_duration": 279
},
{
"cumulative_travel_distance": 29706,
"cumulative_travel_duration": 1485,
"cumulative_travel_distance": 38972,
"cumulative_travel_duration": 1948,
"stop": {
"id": "Fushimi Inari Taisha Copy",
"id": "Fushimi Inari Taisha",
"location": {
"lat": 34.967146,
"lon": 135.72696
"lon": 135.772695
}
},
"travel_distance": 7486,
"travel_duration": 374
"travel_distance": 4167,
"travel_duration": 208
},
{
"cumulative_travel_distance": 35632,
"cumulative_travel_duration": 1781,
"cumulative_travel_distance": 42907,
"cumulative_travel_duration": 2145,
"stop": {
"id": "Gionmachi Copy",
"id": "Gionmachi",
"location": {
"lat": 35.002457,
"lon": 135.775683
"lon": 135.775682
}
},
"travel_distance": 5926,
"travel_duration": 296
"travel_distance": 3935,
"travel_duration": 196
},
{
"cumulative_travel_distance": 36833,
"cumulative_travel_duration": 1841,
"cumulative_travel_distance": 44108,
"cumulative_travel_duration": 2205,
"stop": {
"id": "Kiyomizu-dera",
"location": {
Expand All @@ -258,9 +259,9 @@
"travel_duration": 60
}
],
"route_duration": 1841,
"route_travel_distance": 36833,
"route_travel_duration": 1841
"route_duration": 2205,
"route_travel_distance": 44108,
"route_travel_duration": 2205
}
]
}
Expand All @@ -269,16 +270,16 @@
"result": {
"custom": {
"activated_vehicles": 1,
"max_duration": 1841,
"max_duration": 2205,
"max_stops_in_vehicle": 13,
"max_travel_duration": 1841,
"min_duration": 1841,
"max_travel_duration": 2205,
"min_duration": 2205,
"min_stops_in_vehicle": 13,
"min_travel_duration": 1841,
"min_travel_duration": 2205,
"unplanned_stops": 0
},
"duration": 0.123,
"value": 1841.9036093736736
"value": 2205.7639215043205
},
"run": {
"duration": 0.123,
Expand Down
Loading

0 comments on commit 13fad8b

Please sign in to comment.