mirror of
https://github.com/mudler/luet.git
synced 2025-07-18 01:12:34 +00:00
90 lines
2.6 KiB
Go
90 lines
2.6 KiB
Go
package solver
|
|
|
|
const (
|
|
nbMaxRecent = 50 // How many recent LBD values we consider; "X" in papers about LBD.
|
|
triggerRestartK = 0.8
|
|
nbMaxTrail = 5000 // How many elements in queueTrail we consider; "Y" in papers about LBD.
|
|
postponeRestartT = 1.4
|
|
)
|
|
|
|
type queueData struct {
|
|
totalNb int // Current total nb of values considered
|
|
totalSum int // Sum of all values so far
|
|
nbRecent int // NB of values used in the array
|
|
ptr int // current index of oldest value in the array
|
|
recentAvg float64 // Average value
|
|
}
|
|
|
|
// lbdStats is a structure dealing with recent LBD evolutions.
|
|
type lbdStats struct {
|
|
lbdData queueData
|
|
trailData queueData
|
|
recentVals [nbMaxRecent]int // Last LBD values
|
|
recentTrails [nbMaxTrail]int // Last trail lengths
|
|
}
|
|
|
|
// mustRestart is true iff recent LBDs are much smaller on average than average of all LBDs.
|
|
func (l *lbdStats) mustRestart() bool {
|
|
if l.lbdData.nbRecent < nbMaxRecent {
|
|
return false
|
|
}
|
|
return l.lbdData.recentAvg*triggerRestartK > float64(l.lbdData.totalSum)/float64(l.lbdData.totalNb)
|
|
}
|
|
|
|
// addConflict adds information about a conflict that just happened.
|
|
func (l *lbdStats) addConflict(trailSz int) {
|
|
td := &l.trailData
|
|
td.totalNb++
|
|
td.totalSum += trailSz
|
|
if td.nbRecent < nbMaxTrail {
|
|
l.recentTrails[td.nbRecent] = trailSz
|
|
old := float64(td.nbRecent)
|
|
new := old + 1
|
|
td.recentAvg = (td.recentAvg*old)/new + float64(trailSz)/new
|
|
td.nbRecent++
|
|
} else {
|
|
old := l.recentTrails[td.ptr]
|
|
l.recentTrails[td.ptr] = trailSz
|
|
td.ptr++
|
|
if td.ptr == nbMaxTrail {
|
|
td.ptr = 0
|
|
}
|
|
td.recentAvg = td.recentAvg - float64(old)/nbMaxTrail + float64(trailSz)/nbMaxTrail
|
|
}
|
|
if td.nbRecent == nbMaxTrail && l.lbdData.nbRecent == nbMaxRecent && trailSz > int(postponeRestartT*td.recentAvg) {
|
|
// Too many good assignments: postpone restart
|
|
l.clear()
|
|
}
|
|
|
|
}
|
|
|
|
// addLbd adds information about a recent learned clause's LBD.
|
|
// TODO: this is very close to addConflicts's code, this should probably be rewritten/merged.
|
|
func (l *lbdStats) addLbd(lbd int) {
|
|
ld := &l.lbdData
|
|
ld.totalNb++
|
|
ld.totalSum += lbd
|
|
if ld.nbRecent < nbMaxRecent {
|
|
l.recentVals[ld.nbRecent] = lbd
|
|
old := float64(ld.nbRecent)
|
|
new := old + 1
|
|
ld.recentAvg = (ld.recentAvg*old)/new + float64(lbd)/new
|
|
ld.nbRecent++
|
|
} else {
|
|
old := l.recentVals[ld.ptr]
|
|
l.recentVals[ld.ptr] = lbd
|
|
ld.ptr++
|
|
if ld.ptr == nbMaxRecent {
|
|
ld.ptr = 0
|
|
}
|
|
ld.recentAvg = ld.recentAvg - float64(old)/nbMaxRecent + float64(lbd)/nbMaxRecent
|
|
}
|
|
}
|
|
|
|
// clear clears last values. It should be called after a restart.
|
|
func (l *lbdStats) clear() {
|
|
l.lbdData.ptr = 0
|
|
l.lbdData.nbRecent = 0
|
|
l.lbdData.recentAvg = 0.0
|
|
}
|