Use conditional probability for noWinners, fix tests

Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
This commit is contained in:
Jakub Sztandera 2020-08-18 19:18:53 +02:00
parent 12f7ead55e
commit 8acd926636
No known key found for this signature in database
GPG Key ID: 9A9AF56F8B3879BA
2 changed files with 37 additions and 11 deletions

View File

@ -26,6 +26,28 @@ func noWinnersProb() []float64 {
return noWinnersProbCache
}
var noWinnersProbAssumingCache []float64
var noWinnersProbAssumingOnce sync.Once
func noWinnersProbAssumingMoreThanOne() []float64 {
noWinnersProbAssumingOnce.Do(func() {
cond := math.Log(-1 + math.Exp(5))
poissPdf := func(x float64) float64 {
const Mu = 5
lg, _ := math.Lgamma(x + 1)
result := math.Exp((math.Log(Mu) * x) - lg - cond)
return result
}
out := make([]float64, 0, MaxBlocks)
for i := 0; i < MaxBlocks; i++ {
out = append(out, poissPdf(float64(i+1)))
}
noWinnersProbAssumingCache = out
})
return noWinnersProbAssumingCache
}
func binomialCoefficient(n, k float64) float64 {
if k > n {
return math.NaN()
@ -40,7 +62,7 @@ func binomialCoefficient(n, k float64) float64 {
}
func (mp *MessagePool) blockProbabilities(tq float64) []float64 {
noWinners := noWinnersProb() // cache this
noWinners := noWinnersProbAssumingMoreThanOne()
p := 1 - tq
binoPdf := func(x, trials float64) float64 {

View File

@ -934,9 +934,11 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu
t.Fatal(err)
}
capacityBoost := 0.0
rewardBoost := 0.0
const runs = 1
totalGreedyCapacity := 0.0
totalGreedyReward := 0.0
totalOptimalCapacity := 0.0
totalOptimalReward := 0.0
const runs = 50
for i := 0; i < runs; i++ {
// 2. optimal selection
minersRand := rng.Float64()
@ -945,8 +947,8 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu
for ; i < MaxBlocks && minersRand > 0; i++ {
minersRand -= winerProba[i]
}
nMiners := i
if nMiners == 0 {
nMiners := i - 1
if nMiners < 1 {
nMiners = 1
}
@ -962,14 +964,15 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu
}
}
totalGreedyCapacity += float64(len(greedyMsgs))
totalOptimalCapacity += float64(len(optMsgs))
boost := float64(len(optMsgs)) / float64(len(greedyMsgs))
capacityBoost += boost
t.Logf("nMiners: %d", nMiners)
t.Logf("greedy capacity %d, optimal capacity %d (x %.1f )", len(greedyMsgs),
len(optMsgs), boost)
if len(greedyMsgs) > len(optMsgs) {
t.Fatal("greedy capacity higher than optimal capacity; wtf")
t.Errorf("greedy capacity higher than optimal capacity; wtf")
}
greedyReward := big.NewInt(0)
@ -984,17 +987,18 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu
nMinersBig := big.NewInt(int64(nMiners))
greedyAvgReward, _ := new(big.Rat).SetFrac(greedyReward, nMinersBig).Float64()
totalGreedyReward += greedyAvgReward
optimalAvgReward, _ := new(big.Rat).SetFrac(optReward, nMinersBig).Float64()
totalOptimalReward += optimalAvgReward
boost = optimalAvgReward / greedyAvgReward
rewardBoost += boost
t.Logf("greedy reward: %.0f, optimal reward: %.0f (x %.1f )", greedyAvgReward,
optimalAvgReward, boost)
}
capacityBoost /= runs
rewardBoost /= runs
capacityBoost := totalOptimalCapacity / totalGreedyCapacity
rewardBoost := totalOptimalReward / totalGreedyReward
t.Logf("Average capacity boost: %f", capacityBoost)
t.Logf("Average reward boost: %f", rewardBoost)