12 次代碼提交 8187c0f1f2 ... 5ef8a78866

作者 SHA1 備註 提交日期
  Guillaume Koenig 5ef8a78866 11M on input D by changing scoring function 7 年之前
  Guillaume Koenig 72e8322f2b Revert "Some inputs perform better picking one of the next best rides" 7 年之前
  Guillaume Koenig abcac1b6fd Revert "Prioq can now remove any element if its position is known" 7 年之前
  Guillaume Koenig 654a9971c1 Revert "Recursion to try a few different routes - score: 47.9M" 7 年之前
  Guillaume Koenig d7f9d3c460 Revert "Check recursive algorithm gives a correct result on scoreboard" 7 年之前
  Guillaume Koenig 71ab797b7f Revert "buggy not monte carlo" 7 年之前
  Guillaume Koenig 8cfe1af578 Revert "fix 2 bugs" 7 年之前
  Guillaume Koenig 92b50ddcf5 Revert "super long run "monte carlo" (it's not really mc)" 7 年之前
  Guillaume Koenig d0ce2b5c00 super long run "monte carlo" (it's not really mc) 7 年之前
  Guillaume Koenig ac8d44f380 fix 2 bugs 7 年之前
  Guillaume Koenig 413708b0c1 buggy not monte carlo 7 年之前
  Guillaume Koenig b1a7f7bdbf Check recursive algorithm gives a correct result on scoreboard 7 年之前
共有 1 個文件被更改,包括 60 次插入92 次删除
  1. 60 92
      main.go

+ 60 - 92
main.go

@@ -2,7 +2,6 @@ package main
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"math/rand"
6 5
 	"os"
7 6
 	"sort"
8 7
 )
@@ -66,7 +65,6 @@ func (rs ByEndtime) Less(i, j int) bool {
66 65
 
67 66
 type Scheduler interface {
68 67
 	Add(*Car)
69
-	RemoveAtIndex(k int) *Car
70 68
 	Pop() *Car
71 69
 }
72 70
 
@@ -78,8 +76,7 @@ type Car struct {
78 76
 	X       int
79 77
 	Y       int
80 78
 
81
-	score   int
82
-	pqindex int // used for removal in prority queue
79
+	score int
83 80
 }
84 81
 
85 82
 func (c *Car) Update(r *Ride) {
@@ -135,89 +132,74 @@ func max(a, b int) int {
135 132
 	}
136 133
 }
137 134
 
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
-	}
135
+func (c *Car) CanPick(r *Ride) bool {
136
+	return !r.used && r.f >= c.EarliestFinish(r)
137
+}
154 138
 
155
-	var bestRides []struct {
156
-		r         *Ride
157
-		lenOfRide int
158
-		total     int
159
-	}
160
-	// fmt.Printf("car %d\n", c.ID)
139
+func (c *Car) pickClosestLate() *Ride {
140
+	var best *Ride
141
+	var dbest = 999999999
161 142
 	for _, r := range Rides {
162
-		if r.used {
143
+		if !c.CanPick(r) {
163 144
 			continue
164 145
 		}
165
-		if r.Length() > 6000 {
166
-			continue
146
+		d := c.distanceTo(r.a, r.b)
147
+		if d < dbest && d > r.s-c.Arrival {
148
+			best = r
149
+			dbest = d
167 150
 		}
168
-		if r.f < c.EarliestFinish(r) {
151
+	}
152
+	return best
153
+}
154
+
155
+func Choose(c *Car) *Ride {
156
+	var bestRide *Ride
157
+	bestLenOfRide := 0
158
+	bestTotal := 0
159
+	// fmt.Printf("car %d\n", c.ID)
160
+	for _, r := range Rides {
161
+		if !c.CanPick(r) {
169 162
 			continue
170 163
 		}
171 164
 		// fmt.Printf("%d %d -> %d %d\n", r.a, r.b, r.x, r.y)
172 165
 		lenOfRide := r.length()
173 166
 		total := max(c.distanceTo(r.a, r.b), r.s-c.Arrival) + lenOfRide
174 167
 		// fmt.Printf("%d/%d\n", lenOfRide, total)
175
-		if len(bestRides) == 0 || lenOfRide*bestRides[len(bestRides)-1].total > total*bestRides[len(bestRides)-1].lenOfRide {
176
-			bestRides = append(bestRides, struct {
177
-				r         *Ride
178
-				lenOfRide int
179
-				total     int
180
-			}{r, lenOfRide, total})
181
-			// shitty sort-of-correct-but-quite-incorrect way
182
-			// of picking next best n rides
183
-			n := 1
184
-			if rand.Intn(max(1, int(N/5))) == 0 {
185
-				n = 3
186
-			}
187
-			if len(bestRides) > n {
188
-				bestRides = bestRides[len(bestRides)-n:]
189
-			}
168
+		if bestRide == nil || lenOfRide*bestTotal > total*bestLenOfRide {
169
+			bestLenOfRide = lenOfRide
170
+			bestTotal = total
171
+			bestRide = r
190 172
 		}
191 173
 	}
192 174
 	// if bestRide != nil {
193 175
 	// 	fmt.Printf("Picking %d %d -> %d %d\n", bestRide.a, bestRide.b, bestRide.x, bestRide.y)
194 176
 	// }
195
-	if len(bestRides) != 0 {
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
177
+	if bestRide != nil {
178
+		r := c.pickClosestLate()
179
+		if r != nil {
180
+			bestRide = r
209 181
 		}
210
-	} else {
211
-		// another car may still have other rides
212
-		Choose(cumulativeScore, depth)
213 182
 	}
214
-	// add back the one we popped at beginning of function
183
+	return bestRide
184
+}
185
+
186
+func assign() bool {
187
+	c := Sched.Pop()
188
+	if c == nil {
189
+		return false
190
+	}
191
+	r := Choose(c)
192
+	if r == nil {
193
+		return true
194
+	}
195
+	r.used = true
196
+	c.Update(r)
215 197
 	Sched.Add(c)
198
+
199
+	return true
216 200
 }
217 201
 
218 202
 func solve() {
219
-	rand.Seed(1)
220
-
221 203
 	sort.Sort(ByEndtime(Rides))
222 204
 
223 205
 	Sched = &prioq{}
@@ -234,17 +216,19 @@ func solve() {
234 216
 		Sched.Add(c)
235 217
 	}
236 218
 
237
-	// start recursion
238
-	Choose(0, 0)
219
+	for assign() {
220
+	}
239 221
 
222
+	totalScore := 0
240 223
 	for _, c := range Cars {
241 224
 		fmt.Fprintf(output, "%d", len(c.Rides))
242 225
 		for _, ri := range c.Rides {
243 226
 			fmt.Fprintf(output, " %d", ri)
244 227
 		}
245 228
 		fmt.Fprintf(output, "\n")
229
+		totalScore += c.score
246 230
 	}
247
-	fmt.Printf("%d\n", bestTotalScore)
231
+	fmt.Printf("%d\n", totalScore)
248 232
 }
249 233
 
250 234
 func main() {
@@ -315,36 +299,31 @@ type prioq struct {
315 299
 
316 300
 func (pq *prioq) Add(car *Car) {
317 301
 	pq.bintree = append(pq.bintree, car)
318
-	pq.bintree[len(pq.bintree)-1].pqindex = len(pq.bintree) - 1
319 302
 
320 303
 	// Rebalance tree to respect invariant
321 304
 	var i = len(pq.bintree) - 1
322 305
 	var p = (i - 1) / 2
323 306
 	for p >= 0 && pq.bintree[p].Arrival > pq.bintree[i].Arrival {
324 307
 		pq.bintree[p], pq.bintree[i] = pq.bintree[i], pq.bintree[p]
325
-		pq.bintree[p].pqindex = p
326
-		pq.bintree[i].pqindex = i
327 308
 		i = p
328 309
 		p = (i - 1) / 2
329 310
 	}
330 311
 }
331 312
 
332
-func (pq *prioq) RemoveAtIndex(k int) *Car {
313
+func (pq *prioq) Pop() *Car {
333 314
 	if len(pq.bintree) == 0 {
334 315
 		return nil
335 316
 	}
336 317
 
337
-	if k == len(pq.bintree)-1 {
338
-		elem := pq.bintree[k]
339
-		pq.bintree = pq.bintree[:k]
318
+	if len(pq.bintree) == 1 {
319
+		elem := pq.bintree[0]
320
+		pq.bintree = pq.bintree[:0]
340 321
 		return elem
341 322
 	}
342 323
 
343
-	pq.bintree[k].pqindex = -1
344
-	elem := pq.bintree[k]
345
-	// Put last element at hole
346
-	pq.bintree[k] = pq.bintree[len(pq.bintree)-1]
347
-	pq.bintree[k].pqindex = k
324
+	elem := pq.bintree[0]
325
+	// Put last element at root
326
+	pq.bintree[0] = pq.bintree[len(pq.bintree)-1]
348 327
 	// Remove last element
349 328
 	pq.bintree = pq.bintree[:len(pq.bintree)-1]
350 329
 
@@ -355,8 +334,7 @@ func (pq *prioq) RemoveAtIndex(k int) *Car {
355 334
 
356 335
 	// Rebalance tree to respect invariant
357 336
 	len := len(pq.bintree)
358
-	i := k
359
-	left, right := 0, 0
337
+	i, left, right := 0, 0, 0
360 338
 	for {
361 339
 		left = 2*i + 1
362 340
 		right = 2*i + 2
@@ -366,8 +344,6 @@ func (pq *prioq) RemoveAtIndex(k int) *Car {
366 344
 					break // Inferior to both children
367 345
 				} else {
368 346
 					pq.bintree[i], pq.bintree[left] = pq.bintree[left], pq.bintree[i]
369
-					pq.bintree[i].pqindex = i
370
-					pq.bintree[left].pqindex = left
371 347
 					i = left
372 348
 				}
373 349
 			} else {
@@ -375,8 +351,6 @@ func (pq *prioq) RemoveAtIndex(k int) *Car {
375 351
 					break // Inferior to both children
376 352
 				} else {
377 353
 					pq.bintree[i], pq.bintree[right] = pq.bintree[right], pq.bintree[i]
378
-					pq.bintree[i].pqindex = i
379
-					pq.bintree[right].pqindex = right
380 354
 					i = right
381 355
 				}
382 356
 			}
@@ -385,8 +359,6 @@ func (pq *prioq) RemoveAtIndex(k int) *Car {
385 359
 				break // Inferior to only child
386 360
 			}
387 361
 			pq.bintree[i], pq.bintree[left] = pq.bintree[left], pq.bintree[i]
388
-			pq.bintree[i].pqindex = i
389
-			pq.bintree[left].pqindex = left
390 362
 			i = left
391 363
 		} else { // No child
392 364
 			break
@@ -397,10 +369,6 @@ func (pq *prioq) RemoveAtIndex(k int) *Car {
397 369
 	return elem
398 370
 }
399 371
 
400
-func (pq *prioq) Pop() *Car {
401
-	return pq.RemoveAtIndex(0)
402
-}
403
-
404 372
 func (pq *prioq) empty() bool {
405 373
 	return len(pq.bintree) == 0
406 374
 }