Переглянути джерело

Recursion to try a few different routes - score: 47.9M

Probably not a good strategy for three reasons : a) code is quite a
bit more complex b) gain is all relative (only 15k on third input)
and c) it's long to execute, already ~3.5 minutes

Only score is calculated, not the actual resulting out files (it would
require saving alongside bestTotalScore)
Guillaume Koenig 7 роки тому
батько
коміт
8187c0f1f2
1 змінених файлів з 49 додано та 30 видалено
  1. 49 30
      main.go

+ 49 - 30
main.go

@@ -2,6 +2,7 @@ package main
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"math/rand"
5 6
 	"os"
6 7
 	"sort"
7 8
 )
@@ -134,7 +135,23 @@ func max(a, b int) int {
134 135
 	}
135 136
 }
136 137
 
137
-func Choose(c *Car) *Ride {
138
+var bestTotalScore int
139
+
140
+// invariant : when entering and leaving function,
141
+// Sched has the "same" heap. Same means successive
142
+// popped values will be the same (but the internal
143
+// ordering of nodes may be different)
144
+func Choose(cumulativeScore int, depth int) {
145
+	if cumulativeScore > bestTotalScore {
146
+		bestTotalScore = cumulativeScore
147
+	}
148
+	c := Sched.Pop()
149
+	if c == nil {
150
+		// Stop recursion, empty car list,
151
+		// could not match cars to rides
152
+		return
153
+	}
154
+
138 155
 	var bestRides []struct {
139 156
 		r         *Ride
140 157
 		lenOfRide int
@@ -145,9 +162,9 @@ func Choose(c *Car) *Ride {
145 162
 		if r.used {
146 163
 			continue
147 164
 		}
148
-		// if r.Length() > 6000 {
149
-		// 	continue
150
-		// }
165
+		if r.Length() > 6000 {
166
+			continue
167
+		}
151 168
 		if r.f < c.EarliestFinish(r) {
152 169
 			continue
153 170
 		}
@@ -163,7 +180,10 @@ func Choose(c *Car) *Ride {
163 180
 			}{r, lenOfRide, total})
164 181
 			// shitty sort-of-correct-but-quite-incorrect way
165 182
 			// of picking next best n rides
166
-			n := 3
183
+			n := 1
184
+			if rand.Intn(max(1, int(N/5))) == 0 {
185
+				n = 3
186
+			}
167 187
 			if len(bestRides) > n {
168 188
 				bestRides = bestRides[len(bestRides)-n:]
169 189
 			}
@@ -173,31 +193,31 @@ func Choose(c *Car) *Ride {
173 193
 	// 	fmt.Printf("Picking %d %d -> %d %d\n", bestRide.a, bestRide.b, bestRide.x, bestRide.y)
174 194
 	// }
175 195
 	if len(bestRides) != 0 {
176
-		// pick the not quite best ride...hey some
177
-		// of the inputs already  give a better score !
178
-		return bestRides[0].r
179
-		//return bestRides[len(bestRides)-1].r
180
-	}
181
-	return nil
182
-}
183
-
184
-func assign() bool {
185
-	c := Sched.Pop()
186
-	if c == nil {
187
-		return false
188
-	}
189
-	r := Choose(c)
190
-	if r == nil {
191
-		return true
196
+		for _, br := range bestRides {
197
+			r := br.r
198
+			r.used = true
199
+			oldC := *c
200
+			c.Update(r)
201
+			Sched.Add(c)
202
+			// recursion 101
203
+			Choose(cumulativeScore+c.score-oldC.score, depth+1)
204
+			Sched.RemoveAtIndex(c.pqindex)
205
+			// pqindex is meaningless now but it's ok
206
+			// it will be fixed when c is added again
207
+			*c = oldC
208
+			r.used = false
209
+		}
210
+	} else {
211
+		// another car may still have other rides
212
+		Choose(cumulativeScore, depth)
192 213
 	}
193
-	r.used = true
194
-	c.Update(r)
214
+	// add back the one we popped at beginning of function
195 215
 	Sched.Add(c)
196
-
197
-	return true
198 216
 }
199 217
 
200 218
 func solve() {
219
+	rand.Seed(1)
220
+
201 221
 	sort.Sort(ByEndtime(Rides))
202 222
 
203 223
 	Sched = &prioq{}
@@ -214,19 +234,17 @@ func solve() {
214 234
 		Sched.Add(c)
215 235
 	}
216 236
 
217
-	for assign() {
218
-	}
237
+	// start recursion
238
+	Choose(0, 0)
219 239
 
220
-	totalScore := 0
221 240
 	for _, c := range Cars {
222 241
 		fmt.Fprintf(output, "%d", len(c.Rides))
223 242
 		for _, ri := range c.Rides {
224 243
 			fmt.Fprintf(output, " %d", ri)
225 244
 		}
226 245
 		fmt.Fprintf(output, "\n")
227
-		totalScore += c.score
228 246
 	}
229
-	fmt.Printf("%d\n", totalScore)
247
+	fmt.Printf("%d\n", bestTotalScore)
230 248
 }
231 249
 
232 250
 func main() {
@@ -322,6 +340,7 @@ func (pq *prioq) RemoveAtIndex(k int) *Car {
322 340
 		return elem
323 341
 	}
324 342
 
343
+	pq.bintree[k].pqindex = -1
325 344
 	elem := pq.bintree[k]
326 345
 	// Put last element at hole
327 346
 	pq.bintree[k] = pq.bintree[len(pq.bintree)-1]