@@ -5,7 +5,6 @@ package nextroute
5
5
import (
6
6
"math/rand"
7
7
"slices"
8
- "sync/atomic"
9
8
)
10
9
11
10
// SequenceGeneratorChannel generates all possible sequences of solution stops
@@ -29,54 +28,55 @@ func SequenceGeneratorChannel(
29
28
pu SolutionPlanUnit ,
30
29
quit <- chan struct {},
31
30
) chan SolutionStops {
32
- planUnit := pu .(* solutionPlanStopsUnitImpl )
33
- solution := planUnit .solution ()
34
- maxSequences := int64 (solution .Model ().SequenceSampleSize ())
35
- solutionStops := planUnit .SolutionStops ()
36
31
ch := make (chan SolutionStops )
37
32
go func () {
38
33
defer close (ch )
39
- switch planUnit .ModelPlanStopsUnit ().NumberOfStops () {
40
- case 1 :
41
- ch <- solutionStops
42
- return
43
- default :
44
- used := make ([]bool , len (solutionStops ))
45
- inDegree := map [int ]int {}
46
- modelPlanUnit := planUnit .ModelPlanUnit ().(* planMultipleStopsImpl )
47
- dag := modelPlanUnit .dag .(* directedAcyclicGraphImpl )
48
- for _ , solutionStop := range solutionStops {
49
- inDegree [solutionStop .ModelStop ().Index ()] = 0
50
- }
51
- for _ , arc := range dag .arcs {
52
- inDegree [arc .Destination ().Index ()]++
34
+ sequenceGeneratorSync (pu , func (solutionStops SolutionStops ) {
35
+ select {
36
+ case <- quit :
37
+ return
38
+ case ch <- slices .Clone (solutionStops ):
53
39
}
54
-
55
- sequenceGenerator (
56
- solutionStops ,
57
- make ([]SolutionStop , 0 , len (solutionStops )),
58
- used ,
59
- inDegree ,
60
- dag ,
61
- solution .Random (),
62
- & maxSequences ,
63
- func (solutionStops SolutionStops ) {
64
- select {
65
- case <- quit :
66
- return
67
- case ch <- solutionStops :
68
- }
69
- },
70
- - 1 ,
71
- )
72
- }
40
+ })
73
41
}()
74
42
75
43
return ch
76
44
}
77
45
78
- func sequenceGenerator (
79
- stops , sequence SolutionStops ,
46
+ func sequenceGeneratorSync (pu SolutionPlanUnit , yield func (SolutionStops )) {
47
+ planUnit := pu .(* solutionPlanStopsUnitImpl )
48
+ solutionStops := planUnit .solutionStops
49
+ if planUnit .ModelPlanStopsUnit ().NumberOfStops () == 1 {
50
+ yield (planUnit .SolutionStops ())
51
+ return
52
+ }
53
+ solution := planUnit .solution ()
54
+ maxSequences := int64 (solution .Model ().SequenceSampleSize ())
55
+ nSolutionStops := len (solutionStops )
56
+ used := make ([]bool , nSolutionStops )
57
+ inDegree := make (map [int ]int , nSolutionStops )
58
+ modelPlanUnit := planUnit .ModelPlanUnit ().(* planMultipleStopsImpl )
59
+ dag := modelPlanUnit .dag .(* directedAcyclicGraphImpl )
60
+ for _ , arc := range dag .arcs {
61
+ inDegree [arc .Destination ().Index ()]++
62
+ }
63
+
64
+ recursiveSequenceGenerator (
65
+ solutionStops ,
66
+ make ([]SolutionStop , 0 , nSolutionStops ),
67
+ used ,
68
+ inDegree ,
69
+ dag ,
70
+ solution .Random (),
71
+ & maxSequences ,
72
+ yield ,
73
+ - 1 ,
74
+ )
75
+ }
76
+
77
+ func recursiveSequenceGenerator (
78
+ stops []SolutionStop ,
79
+ sequence SolutionStops ,
80
80
used []bool ,
81
81
inDegree map [int ]int ,
82
82
dag DirectedAcyclicGraph ,
@@ -85,21 +85,27 @@ func sequenceGenerator(
85
85
yield func (SolutionStops ),
86
86
directSuccessor int ,
87
87
) {
88
- if len (sequence ) == len (stops ) {
89
- if atomic .AddInt64 (maxSequences , - 1 ) >= 0 {
90
- yield (slices .Clone (sequence ))
88
+ if * maxSequences == 0 {
89
+ return
90
+ }
91
+ nStops := len (stops )
92
+ if len (sequence ) == nStops {
93
+ * maxSequences --
94
+ if * maxSequences >= 0 {
95
+ yield (sequence )
91
96
}
92
97
return
93
98
}
94
99
95
- stopOrder := random .Perm (len ( stops ) )
100
+ stopOrder := random .Perm (nStops )
96
101
97
102
// we know the direct successor, so we move it to the front of the random
98
103
// sequence
99
104
if directSuccessor != - 1 {
100
105
for _ , stopIdx := range stopOrder {
101
106
if stops [stopIdx ].Index () == directSuccessor {
102
- stopOrder = []int {stopIdx }
107
+ stopOrder = stopOrder [:1 ]
108
+ stopOrder [0 ] = stopIdx
103
109
break
104
110
}
105
111
}
@@ -128,7 +134,9 @@ func sequenceGenerator(
128
134
}
129
135
}
130
136
}
131
- sequenceGenerator (stops , append (sequence , stop ), used , inDegree , dag , random , maxSequences , yield , directSuccessor )
137
+ recursiveSequenceGenerator (
138
+ stops , append (sequence , stop ), used , inDegree , dag , random , maxSequences , yield , directSuccessor ,
139
+ )
132
140
// reached the maximum number of sequences
133
141
if * maxSequences == 0 {
134
142
return
0 commit comments