Add iterated local search to solver for more stable results
This commit is contained in:
48
main.go
48
main.go
@@ -1066,13 +1066,9 @@ func handleSolve(db *sql.DB) http.HandlerFunc {
|
|||||||
return currentScore
|
return currentScore
|
||||||
}
|
}
|
||||||
|
|
||||||
for restart := 0; restart < 50; restart++ {
|
randomPlacement := func() bool {
|
||||||
if restart == 0 {
|
|
||||||
copy(assignment, initialAssignment)
|
|
||||||
} else {
|
|
||||||
perm := rand.Perm(len(groupList))
|
perm := rand.Perm(len(groupList))
|
||||||
for i := range roomCap { roomCap[i] = roomSize }
|
for i := range roomCap { roomCap[i] = roomSize }
|
||||||
ok := true
|
|
||||||
for _, pi := range perm {
|
for _, pi := range perm {
|
||||||
grp := groupList[pi]
|
grp := groupList[pi]
|
||||||
placed := false
|
placed := false
|
||||||
@@ -1098,16 +1094,48 @@ func handleSolve(db *sql.DB) http.HandlerFunc {
|
|||||||
placed = true
|
placed = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if !placed {
|
if !placed { return false }
|
||||||
ok = false
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
perturb := func(src []int, count int) {
|
||||||
|
copy(assignment, src)
|
||||||
|
indices := rand.Perm(len(uniqueGroups))
|
||||||
|
if count > len(indices) { count = len(indices) }
|
||||||
|
for _, gi := range indices[:count] {
|
||||||
|
grp := groups[uniqueGroups[gi]]
|
||||||
|
oldRoom := assignment[grp[0]]
|
||||||
|
rooms := rand.Perm(numRooms)
|
||||||
|
for _, room := range rooms {
|
||||||
|
if room == oldRoom { continue }
|
||||||
|
if roomCount(assignment, room)+len(grp) > roomSize { continue }
|
||||||
|
for _, m := range grp { assignment[m] = room }
|
||||||
|
if feasible(assignment) { break }
|
||||||
|
for _, m := range grp { assignment[m] = oldRoom }
|
||||||
}
|
}
|
||||||
if !ok {
|
|
||||||
copy(assignment, initialAssignment)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copy(assignment, initialAssignment)
|
||||||
|
s := hillClimb(assignment)
|
||||||
|
if s > bestScore {
|
||||||
|
bestScore = s
|
||||||
|
copy(bestAssignment, assignment)
|
||||||
|
}
|
||||||
|
|
||||||
|
for restart := 0; restart < 30; restart++ {
|
||||||
|
if randomPlacement() {
|
||||||
|
s := hillClimb(assignment)
|
||||||
|
if s > bestScore {
|
||||||
|
bestScore = s
|
||||||
|
copy(bestAssignment, assignment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ils := 0; ils < 200; ils++ {
|
||||||
|
perturb(bestAssignment, 2+rand.Intn(3))
|
||||||
s := hillClimb(assignment)
|
s := hillClimb(assignment)
|
||||||
if s > bestScore {
|
if s > bestScore {
|
||||||
bestScore = s
|
bestScore = s
|
||||||
|
|||||||
Reference in New Issue
Block a user