Pārlūkot izejas kodu

buggy not monte carlo

Guillaume Koenig 7 gadi atpakaļ
vecāks
revīzija
413708b0c1
1 mainītis faili ar 102 papildinājumiem un 69 dzēšanām
  1. 102 69
      main.go

+ 102 - 69
main.go

@@ -154,92 +154,125 @@ func save() {
154 154
 	fmt.Printf("%d\n", bestTotalScore)
155 155
 }
156 156
 
157
-// invariant : when entering and leaving function,
158
-// Sched has the "same" heap. Same means successive
159
-// popped values will be the same (but the internal
160
-// ordering of nodes may be different)
161
-func Choose(cumulativeScore int, depth int) {
162
-	if cumulativeScore > bestTotalScore {
163
-		bestTotalScore = cumulativeScore
164
-		save()
165
-	}
166
-	c := Sched.Pop()
167
-	if c == nil {
168
-		// Stop recursion, empty car list,
169
-		// could not match cars to rides
170
-		return
171
-	}
157
+func (c *Car) AssignRideRecur(r *Ride, cumulativeScore int, depth int, fromDepth int) (int, bool) {
158
+	r.used = true
159
+	oldC := *c
160
+	c.Update(r)
161
+	Sched.Add(c)
162
+	// recursion 101
163
+	rdepth, fix := Choose(cumulativeScore+c.score-oldC.score, depth+1, fromDepth)
164
+	Sched.RemoveAtIndex(c.pqindex)
165
+	// pqindex is meaningless now but it's ok
166
+	// it will be fixed when c is added again
167
+	*c = oldC
168
+	r.used = false
169
+	return rdepth, fix
170
+}
171
+
172
+func (c *Car) CanPick(r *Ride) bool {
173
+	return !r.used && r.Length() <= 8000 && r.f >= c.EarliestFinish(r)
174
+}
175
+
176
+func (c *Car) pickBestRide() *Ride {
177
+	var bestRide *Ride
178
+	var bestRideTotal int
179
+	var bestRideLen int
172 180
 
173
-	var bestRides []struct {
174
-		r         *Ride
175
-		lenOfRide int
176
-		total     int
177
-	}
178
-	// fmt.Printf("car %d\n", c.ID)
179 181
 	for _, r := range Rides {
180
-		if r.used {
182
+		if !c.CanPick(r) {
181 183
 			continue
182 184
 		}
183
-		if r.Length() > 8000 {
185
+
186
+		lenOfRide := r.length()
187
+		total := max(c.distanceTo(r.a, r.b), r.s-c.Arrival) + lenOfRide
188
+		if bestRide == nil || lenOfRide*bestRideTotal > total*bestRideLen {
189
+			bestRide = r
190
+			bestRideLen = lenOfRide
191
+			bestRideTotal = total
192
+		}
193
+	}
194
+
195
+	return bestRide
196
+}
197
+
198
+func (c *Car) pickRandomRide() *Ride {
199
+	count := 0
200
+	for _, r := range Rides {
201
+		if !c.CanPick(r) {
184 202
 			continue
185 203
 		}
186
-		if r.f < c.EarliestFinish(r) {
204
+		count++
205
+	}
206
+	i := rand.Intn(count)
207
+	for _, r := range Rides {
208
+		if !c.CanPick(r) {
187 209
 			continue
188 210
 		}
189
-		// fmt.Printf("%d %d -> %d %d\n", r.a, r.b, r.x, r.y)
190
-		lenOfRide := r.length()
191
-		total := max(c.distanceTo(r.a, r.b), r.s-c.Arrival) + lenOfRide
192
-		// fmt.Printf("%d/%d\n", lenOfRide, total)
193
-		if len(bestRides) == 0 || lenOfRide*bestRides[len(bestRides)-1].total > total*bestRides[len(bestRides)-1].lenOfRide {
194
-			bestRides = append(bestRides, struct {
195
-				r         *Ride
196
-				lenOfRide int
197
-				total     int
198
-			}{r, lenOfRide, total})
199
-			// shitty sort-of-correct-but-quite-incorrect way
200
-			// of picking next best n rides
201
-			n := 1
202
-			if rand.Intn(max(1, int(N/20))) == 0 {
203
-				n = 2
204
-			}
205
-			if len(bestRides) > n {
206
-				bestRides = bestRides[len(bestRides)-n:]
207
-			}
211
+		if i == 0 {
212
+			return r
208 213
 		}
214
+		i = i - 1
209 215
 	}
210
-	// if bestRide != nil {
211
-	// 	fmt.Printf("Picking %d %d -> %d %d\n", bestRide.a, bestRide.b, bestRide.x, bestRide.y)
212
-	// }
213
-	if len(bestRides) != 0 {
214
-		if (len(bestRides)) >= 2 {
215
-			// if big difference in length, try both
216
-			// otherwise pick best according to score
217
-			d := abs(bestRides[0].r.length() - bestRides[1].r.length())
218
-			if d < 1000 {
219
-				bestRides = bestRides[1:]
220
-			}
216
+	return nil
217
+}
221 218
 
219
+// invariant : when entering and leaving function,
220
+// Sched has the "same" heap. Same means successive
221
+// popped values will be the same (but the internal
222
+// ordering of nodes may be different)
223
+// Return value (a,b) :
224
+// - rdepth >= 0 return back to that depth
225
+// - rdepth < 0 completely unwind stack and finish
226
+// - fix == false try to make a change at depth `rdepth'
227
+// - fix == true change back, use "optimal" ride again
228
+func Choose(cumulativeScore int, depth int, fromDepth int) (int, bool) {
229
+	c := Sched.Pop()
230
+	if c == nil {
231
+		// At this point we have a complete configuration
232
+		fmt.Printf("score obtained: %d depth: %d\n", cumulativeScore, depth)
233
+		// INVESTIGATE HERE : why do we have different scores ???
234
+		// when we're only asking to fix 22 down in the stack
235
+		return 8270, true
236
+		if cumulativeScore >= bestTotalScore {
237
+			bestTotalScore = cumulativeScore
238
+			// Go back to random depth and make a new change
239
+			return rand.Intn(depth), false
240
+		} else {
241
+			// Go back to fix change that lowered our score
242
+			return fromDepth, true
222 243
 		}
223
-		for _, br := range bestRides {
224
-			r := br.r
225
-			r.used = true
226
-			oldC := *c
227
-			c.Update(r)
228
-			Sched.Add(c)
229
-			// recursion 101
230
-			Choose(cumulativeScore+c.score-oldC.score, depth+1)
231
-			Sched.RemoveAtIndex(c.pqindex)
232
-			// pqindex is meaningless now but it's ok
233
-			// it will be fixed when c is added again
234
-			*c = oldC
235
-			r.used = false
244
+	}
245
+
246
+	var rdepth int
247
+	var fix bool
248
+	r := c.pickBestRide()
249
+	// if depth >= 252 && depth <= 258 {
250
+	// 	fmt.Printf("yo picking id %d score %d c=%+v\n", r.ID, cumulativeScore, c)
251
+	// }
252
+	if r != nil {
253
+		rdepth, fix = c.AssignRideRecur(r, cumulativeScore, depth, fromDepth)
254
+		// if depth == reverse depth, make a change
255
+		// and go back up the stack
256
+		for depth == rdepth {
257
+			var r *Ride
258
+			if fix {
259
+				r = c.pickBestRide()
260
+				fmt.Printf("pickBestRide id %d depth %d\n", r.ID, depth)
261
+			} else {
262
+				r = c.pickRandomRide()
263
+				fmt.Printf("pickRandomRide id %d depth %d\n", r.ID, depth)
264
+			}
265
+			// note fromDepth reset to depth
266
+			rdepth, fix = c.AssignRideRecur(r, cumulativeScore, depth, depth)
236 267
 		}
237 268
 	} else {
238 269
 		// another car may still have other rides
239
-		Choose(cumulativeScore, depth)
270
+		rdepth, fix = Choose(cumulativeScore, depth, fromDepth)
240 271
 	}
241 272
 	// add back the one we popped at beginning of function
242 273
 	Sched.Add(c)
274
+	// go back down the stack
275
+	return rdepth, fix
243 276
 }
244 277
 
245 278
 func solve() {
@@ -262,7 +295,7 @@ func solve() {
262 295
 	}
263 296
 
264 297
 	// start recursion
265
-	Choose(0, 0)
298
+	Choose(0, 0, 0)
266 299
 }
267 300
 
268 301
 func main() {