Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding tiebreaker order #379

Merged
merged 2 commits into from
Nov 14, 2023
Merged

Conversation

mikefranze
Copy link
Collaborator

Description

Previously random tiebreakers used a random number generator inside the tabulators to determine results. This issue with this is results would change every time you calculated them.

This adds a tiebreaker order list input to the tabulators so the outcome is determinative. The list uses strings so UUIDs can be used. To break a tie, the candidate with the lower string value wins. For example, 'A' defeats 'B', '0' defeats '1'. If no list is defined it defaults to using candidate index.

Now that candidate IDs are UUIDs, they can be used for their tiebreaker order so that random ties can be random but still determinative.

@ArendPeter
Copy link
Member

With this implementation the candidates can know ahead of time which one will get tie breaker priority before the election

How would you feel if we used a random number generator, but use "current vote count + the election id" as the seed? That way the result can't be predicted, but recalculating with the same set of votes will give the same result

@mikefranze
Copy link
Collaborator Author

With this implementation the candidates can know ahead of time which one will get tie breaker priority before the election

How would you feel if we used a random number generator, but use "current vote count + the election id" as the seed? That way the result can't be predicted, but recalculating with the same set of votes will give the same result

Done. I'm not necessary against the tiebreak order being known in advance, but your idea is probably a better approach.

Copy link
Member

@ArendPeter ArendPeter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@@ -41,6 +41,7 @@
"pg-boss": "^8.0.0",
"pg-format": "^1.0.4",
"qs": "^6.10.3",
"seedrandom": "^3.0.5",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised the base math class didn't support seeding, weird

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea its frustrating. That's why I didn't go with seeds before, but I found a library that does it.

@@ -48,8 +49,11 @@ const getElectionResults = async (req: IElectionRequest, res: Response, next: Ne
}
const msg = `Tabulating results for ${voting_method} election`
Logger.info(req, msg);
results[race_index] = VotingMethods[voting_method](candidateNames, cvr, num_winners)
let rng = seedrandom(election.election_id + ballots.length.toString())
const tieBreakOrders = election.races[race_index].candidates.map((Candidate) => (rng() as number))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was initially confused here since rng() outputs floats, but the test cases work with lists of unique integers. But it looks like it'll work fine. I guess it's technically possible for rng() to output the same number twice? but I'm not worried about that

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not worried about duplicate floats. And I think in JS integers are just treated as floats.

@mikefranze mikefranze merged commit c987c5c into Equal-Vote:main Nov 14, 2023
3 checks passed
@mikefranze mikefranze deleted the random-tiebreakers branch December 9, 2023 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants