ch.openchvote.simulator.random.RandomVotingStrategy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simulator Show documentation
Show all versions of simulator Show documentation
This module provides an election simulator class, which can be used for simulating CHVote election events based
on various parameters.
/*
* Copyright (C) 2024 Berner Fachhochschule https://e-voting.bfh.ch
*
* - This program is free software: you can redistribute it and/or modify -
* - it under the terms of the GNU Affero General Public License as published by -
* - the Free Software Foundation, either version 3 of the License, or -
* - (at your option) any later version. -
* - -
* - This program is distributed in the hope that it will be useful, -
* - but WITHOUT ANY WARRANTY; without even the implied warranty of -
* - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -
* - GNU General Public License for more details. -
* - -
* - You should have received a copy of the GNU Affero General Public License -
* - along with this program. If not, see . -
*/
package ch.openchvote.simulator.random;
import ch.openchvote.algorithms.protocols.plain.model.VotingParametersPlain;
import ch.openchvote.algorithms.protocols.writein.model.VotingParametersWriteIn;
import ch.openchvote.algorithms.protocols.writein.model.WriteIn;
import ch.openchvote.simulator.SimulationConfiguration;
import ch.openchvote.utilities.sequence.IntVector;
import ch.openchvote.utilities.sequence.Vector;
import ch.openchvote.utilities.set.IntSet;
import ch.openchvote.utilities.tools.RandomFactory;
import ch.openchvote.voter.VotingStrategy;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
/**
* Instances of this class can be used by a voter to select the candidates in a simulated election event.
*/
public class RandomVotingStrategy implements VotingStrategy {
private final double p_participation;
private final Random random;
/**
* Constructs a new voting strategy based on a given simulation configuration.
*
* @param simulationConfiguration The given simulation configuration
*/
public RandomVotingStrategy(SimulationConfiguration simulationConfiguration) {
this(simulationConfiguration.getProbParticipation(), simulationConfiguration.getRandomFactoryMode());
}
/**
* Constructs a new voting strategy. Its behaviour is mainly determined by the node of operation of the random
* generator, which is initialized by this constructor.
*
* @param p_participation The probability of the voter to participate in the election event
* @param mode The mode of operation for the random generator
*/
public RandomVotingStrategy(double p_participation, RandomFactory.Mode mode) {
this.p_participation = p_participation;
this.random = RandomFactory.getInstance(mode);
}
@Override
public int getParticipationBit() {
return (this.random.nextDouble() <= this.p_participation) ? 1 : 0;
}
@Override
public IntSet getSelection(VotingParametersPlain votingParameters) {
return this.getSelection(votingParameters.get_bold_n(), votingParameters.get_bold_k(), votingParameters.get_bold_hat_e_v(), null);
}
@Override
public IntSet getSelection(VotingParametersWriteIn votingParameters) {
return this.getSelection(votingParameters.get_bold_n(), votingParameters.get_bold_k(), votingParameters.get_bold_e_hat_v(), votingParameters.get_bold_v());
}
@Override
public Vector getWriteIns(IntSet S, VotingParametersWriteIn votingParameters) {
return this.getWriteIns(S, votingParameters.get_bold_n(), votingParameters.get_bold_k(), votingParameters.get_bold_e_hat_v(), votingParameters.get_bold_v(), votingParameters.get_bold_z());
}
// private helper method for generating the set of candidates
private IntSet getSelection(IntVector bold_n, IntVector bold_k, IntVector bold_e_hat_v, IntVector bold_v) {
var S = new TreeSet();
int t = bold_n.getLength();
int n_prime = 0;
for (int l : IntSet.range(1, t)) {
int n_l = bold_n.getValue(l);
int k_l = bold_k.getValue(l);
if (bold_e_hat_v.getValue(l) == 1) {
this.getSelection(S, n_l, k_l, n_prime, bold_v);
}
n_prime = n_prime + n_l;
}
return IntSet.of(S);
}
// selecting the candidates in case of write-in elections must guarantee the ordering constraints described in Section 9.1.2.2
private void getSelection(Set S, int n_j, int k_j, int n_prime, IntVector bold_v) {
int skipped = 0; // number of write-in candidates to skip
int k = k_j; // remaining number of selections
int n = n_j; // remaining number of candidates
int i = n_prime + 1; // current candidate index
while (k > 0) {
int v_i = (bold_v == null) ? 0 : bold_v.getValue(i);
if (v_i == 1 && skipped > 0) {
skipped--;
} else if (this.random.nextInt(n) < k) {
S.add(i);
k--;
if (v_i == 0) {
skipped++;
}
}
i++;
n--;
}
}
// private helper method for generating the write-in candidates
private Vector getWriteIns(IntSet S, IntVector bold_n, IntVector bold_k, IntVector bold_e_hat, IntVector bold_v, IntVector bold_z) {
var z_prime = bold_e_hat.multiply(bold_z.times(bold_k));
var builder_bold_s_prime = new Vector.Builder(z_prime);
int t = bold_n.getLength();
int n_prime = 0;
for (int l : IntSet.range(1, t)) {
var n_l = bold_n.getValue(l);
var e_hat_l = bold_e_hat.getValue(l);
var z_l = bold_z.getValue(l);
if (e_hat_l == 1 && z_l == 1) {
for (int i : IntSet.range(n_prime + 1, n_prime + n_l)) {
var v_i = bold_v.getValue(i);
if (S.contains(i)) {
if (v_i == 1) {
builder_bold_s_prime.add(new WriteIn(this.getRandomFirstName(), this.getRandomLastName()));
} else {
builder_bold_s_prime.add(WriteIn.EMPTY);
}
}
}
}
n_prime = n_prime + n_l;
}
return builder_bold_s_prime.build();
}
// private helper method for generating random first names
private String getRandomFirstName() {
int i = this.random.nextInt(FIRST_NAMES.length);
return FIRST_NAMES[i];
}
// private helper method for generating random last names
private String getRandomLastName() {
int i = this.random.nextInt(LAST_NAMES.length);
return LAST_NAMES[i];
}
// two arrays of exemplary first and last names
static private final String[] FIRST_NAMES = {"Eileen", "Lorretta", "Merle", "Brooke", "Sana", "Devorah", "Melaine", "Chantell", "Annamae", "Chong", "Toby", "Jeannie", "Genna", "Reita", "Pierre", "Kary", "Marta", "Josephine", "Glenda", "Suzanne", "Robyn", "Oma", "Tresa", "Eustolia", "Delma", "Tonia", "Kathy", "Lavenia", "Darrick", "Abe", "Patsy", "Eleni", "Lester"};
static private final String[] LAST_NAMES = {"Jarvie", "Schillaci", "Brass", "Koss", "Birdwell", "Bauch", "Lineberger", "Mencer", "Mitchem", "Dews", "Moreland", "Catlin", "Millette", "Clements", "Bastin", "Riter", "Bhatt", "Aichele", "Funnell", "Frazer", "Bordelon", "Huggard", "Auger", "Comiskey", "Dacosta", "Renegar", "Ringler", "Rodarte", "Naval", "Haydel", "Briant"};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy