govote icon indicating copy to clipboard operation
govote copied to clipboard

Partial ballots

Open loopfz opened this issue 5 years ago • 4 comments

Testing schulze / instant-runoff, I notice that when using partial ballots the values not present in any ballot are heavily favored as winners.

I think this fixes the behavior for instant-runoff:

 func (p *InstantRunoffPoll) runRound(elim map[string]bool) map[string]int {
    tally := make(map[string]int)                // scores keyed by candidate name
+   for _, c := range p.candidates {
+        if !elim[c] {
+            tally[c] = 0
+        }
+   }

I haven't looked into schulze yet.

What do you think?

loopfz avatar Dec 02 '20 13:12 loopfz

I'll take a look when I have a moment, thanks. Any chance you could post an example of expected vs erroneous results?

Sam-Izdat avatar Dec 02 '20 17:12 Sam-Izdat

Sure:

func main() {
    candidates := []string{"a", "b", "c", "d"}

    poll, _ := govote.Schulze.New(candidates)

    poll.AddBallot([]string{"a", "b"})
    poll.AddBallot([]string{"a", "c"})
    poll.AddBallot([]string{"c"})
    fmt.Println(poll.Evaluate())
}

Results in:

[a d] [{a 3} {d 3} {b 2} {c 2}] <nil>

loopfz avatar Dec 02 '20 19:12 loopfz

And with instant runoff

func main() {
    candidates := []string{"a", "b", "c", "d"}

    poll, _ := govote.InstantRunoff.New(candidates)

    poll.AddBallot([]string{"a", "b"})
    poll.AddBallot([]string{"a", "c"})
    poll.AddBallot([]string{"c"})
    fmt.Println(poll.Evaluate())
}

Result =

[a b d] [[{a 2} {c 1}] [{a 2}]] <nil>

loopfz avatar Dec 02 '20 19:12 loopfz

Have you had a chance to look into it ?

loopfz avatar Dec 11 '20 14:12 loopfz