Skip to content

Commit

Permalink
Multiwinner: change ints referring to candidates from int to size_t.
Browse files Browse the repository at this point in the history
Also add some patches to range_stv and qrange_stv so they remove ballots
with negative weight. I'm not sure if this is the right thing to do, but
at least I can test them without exceptions being thrown now. Fix later.
  • Loading branch information
kristomu committed Sep 1, 2024
1 parent 8878608 commit 85d921c
Show file tree
Hide file tree
Showing 32 changed files with 184 additions and 335 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ target_link_libraries(qe_singlewinner_methods ${GLPK_LIBRARIES})
add_library(qe_multiwinner_methods
src/multiwinner/auction.cc
src/multiwinner/exhaustive/scored_method.cc
src/multiwinner/helper/dsc.cc
src/multiwinner/helper/errors.cc
src/multiwinner/compat_qbuck.cc
src/multiwinner/dhwl.cc
Expand Down
26 changes: 13 additions & 13 deletions src/main/multiwinner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ vector<double> sum_opinion_profile(const vector<vector<bool> > &
return (opinion_count);
}

vector<double> get_quantized_opinion_profile(const list<int> & candidates,
vector<double> get_quantized_opinion_profile(const list<size_t> &
candidates,
const vector<vector<bool> > & population_profiles) {

// Same as above, really, only with a subset.
Expand All @@ -119,7 +120,7 @@ vector<double> get_quantized_opinion_profile(const list<int> & candidates,

size_t counter, sec;

for (list<int>::const_iterator pos = candidates.begin(); pos !=
for (list<size_t>::const_iterator pos = candidates.begin(); pos !=
candidates.end(); ++pos)
for (sec = 0; sec < opinion_count.size(); ++sec)
if (population_profiles[*pos][sec]) {
Expand Down Expand Up @@ -210,7 +211,7 @@ election_t construct_ballots(const vector<vector<bool> > &

// Framing

list<int> random_council(size_t num_candidates, size_t council_size) {
list<size_t> random_council(size_t num_candidates, size_t council_size) {

vector<int> numbered_candidates(num_candidates);

Expand All @@ -219,15 +220,15 @@ list<int> random_council(size_t num_candidates, size_t council_size) {
iota(numbered_candidates.begin(), numbered_candidates.end(), 0);
random_shuffle(numbered_candidates.begin(), numbered_candidates.end());

list<int> toRet;
list<size_t> toRet;

copy(numbered_candidates.begin(), numbered_candidates.begin() +
council_size, inserter(toRet, toRet.begin()));

return (toRet);
return toRet;
}

double get_error(const list<int> & council,
double get_error(const list<size_t> & council,
int num_candidates, size_t council_size,
const vector<vector<bool> > & population_profiles,
const vector<double> & whole_pop_profile) {
Expand All @@ -239,7 +240,7 @@ double get_error(const list<int> & council,
// Check that there's no double-entry and that the method hasn't
// elected someone outside of the allowed range.
vector<bool> seen(num_candidates, false);
for (list<int>::const_iterator pos = council.begin();
for (list<size_t>::const_iterator pos = council.begin();
pos != council.end(); ++pos) {

assert(0 <= *pos && *pos < num_candidates);
Expand Down Expand Up @@ -303,7 +304,7 @@ double get_optimal_utility(std::vector<double> utilities,
}

double get_council_utility(const std::vector<double> & utilities,
std::list<int> & council) {
std::list<size_t> & council) {

double sum_utils = 0;

Expand Down Expand Up @@ -400,7 +401,7 @@ double random_dictator(const election_t & election,
size_t cands_picked = 0;

assert(ballot.contents.size() >= council_size);
std::list<int> dictatorial_council;
std::list<size_t> dictatorial_council;

for (auto pos = ballot.contents.begin();
cands_picked < council_size && pos != ballot.contents.end();
Expand Down Expand Up @@ -828,13 +829,12 @@ int main(int argc, char * * argv) {
continue;
}

std::list<int> council = e_methods[counter].method()->
std::list<size_t> council = e_methods[counter].method()->
get_council(council_size,
num_candidates, ballots);

error = get_error(council,
num_candidates, council_size,
population_profiles,
error = get_error(council, num_candidates,
council_size, population_profiles,
pop_opinion_profile);

e_methods[counter].add_result(rdic_value, error, cur_best_disprop);
Expand Down
12 changes: 7 additions & 5 deletions src/multiwinner/auction.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
int r_auction::elect_and_update(std::vector<bool> & elected,
std::vector<double> & account_balance,
const election_t & ballots, double minimum,
double maximum, int num_candidates, bool cumulative) const {
double maximum, size_t num_candidates, bool cumulative) const {

// Some sanity checks.
assert(num_candidates > 0);
Expand Down Expand Up @@ -42,7 +42,7 @@ int r_auction::elect_and_update(std::vector<bool> & elected,
sec != pos->contents.end(); ++sec) {
assert(sec->get_candidate_num() >= 0 &&
sec->get_candidate_num() <
(size_t)num_candidates);
num_candidates);

if (elected[sec->get_candidate_num()]) {
continue;
Expand Down Expand Up @@ -116,7 +116,8 @@ int r_auction::elect_and_update(std::vector<bool> & elected,
return (record_pos); // next winner
}

std::list<int> r_auction::get_council(int council_size, int num_candidates,
std::list<size_t> r_auction::get_council(size_t council_size,
size_t num_candidates,
const election_t & ballots) const {

std::vector<bool> elected(num_candidates, false);
Expand All @@ -126,13 +127,14 @@ std::list<int> r_auction::get_council(int council_size, int num_candidates,

double minimum = 0, maximum = 100; // FIX LATER

std::list<int> council;
std::list<size_t> council;

for (int counter = 0; counter < council_size; ++counter)
for (size_t counter = 0; counter < council_size; ++counter) {
// Bad programmer, bad! (Side effects ahoy.)
council.push_back(elect_and_update(elected, account_balance,
ballots, minimum, maximum,
num_candidates, cumul_setting));
}

return (council);
}
4 changes: 2 additions & 2 deletions src/multiwinner/auction.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ class r_auction : public multiwinner_method {
std::vector<double> & account_balance,
const election_t & ballots,
double minimum, double maximum,
int num_candidates, bool cumulative) const;
size_t num_candidates, bool cumulative) const;

bool cumul_setting;

public:
std::list<int> get_council(int council_size, int num_candidates,
std::list<size_t> get_council(size_t council_size, size_t num_candidates,
const election_t & ballots) const;

r_auction(bool cumul_in) {
Expand Down
16 changes: 8 additions & 8 deletions src/multiwinner/compat_qbuck.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// format doesn't have a parameter for that. Besides, this is only intended to
// be scaffolding. Needs CLEANUP.
std::vector<std::vector<int> > old_qltd_pr::construct_old_ballots(
const election_t & ballots, int num_candidates) const {
const election_t & ballots, size_t num_candidates) const {

std::vector<std::vector<int> > out_ballots;

Expand Down Expand Up @@ -42,7 +42,7 @@ std::vector<std::vector<int> > old_qltd_pr::construct_old_ballots(
std::vector<int> old_qltd_pr::QuotaBucklin(
const election_t & ballots,
const std::vector<std::vector<int> > & rankings,
int num_candidates, int council_size, bool hare, bool use_card,
size_t num_candidates, size_t council_size, bool hare, bool use_card,
const std::vector<std::vector<double> > * rated_ballots) const {

// Of those that aren't elected, count the p first candidates into a
Expand Down Expand Up @@ -75,7 +75,7 @@ std::vector<int> old_qltd_pr::QuotaBucklin(
double surplus;
bool failsafe = false;

int elected_candidates = 0;
size_t elected_candidates = 0;

// Do Meek-type binary search to find the round value where a vote goes
// just above the quota. (Actually, that would be a sort of bisection
Expand Down Expand Up @@ -221,7 +221,7 @@ std::vector<int> old_qltd_pr::QuotaBucklin(
int found = -1, found_count = 0;
double found_record = -1;
double irrespec_record = -1;
std::list<int> candidates_past_quota;
std::list<size_t> candidates_past_quota;
for (counter = 0; counter < tally.size(); ++counter) {
if (elected[counter]) {
continue;
Expand Down Expand Up @@ -249,7 +249,7 @@ std::vector<int> old_qltd_pr::QuotaBucklin(
if (found_count > 1) {
std::vector<bool> hopefuls(num_candidates, false);

for (std::list<int>::const_iterator lpos =
for (std::list<size_t>::const_iterator lpos =
candidates_past_quota.begin();
lpos != candidates_past_quota.end();
++lpos) {
Expand Down Expand Up @@ -329,16 +329,16 @@ std::vector<int> old_qltd_pr::QuotaBucklin(
return (allocated);
}

std::list<int> old_qltd_pr::get_council(int council_size,
int num_candidates, const election_t & ballots) const {
std::list<size_t> old_qltd_pr::get_council(size_t council_size,
size_t num_candidates, const election_t & ballots) const {

std::vector<std::vector<int> > translated = construct_old_ballots(ballots,
num_candidates);

std::vector<int> retval = QuotaBucklin(ballots, translated,
num_candidates, council_size, false, false, NULL);

std::list<int> council;
std::list<size_t> council;

copy(retval.begin(), retval.end(), inserter(council, council.begin()));

Expand Down
6 changes: 3 additions & 3 deletions src/multiwinner/compat_qbuck.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@
class old_qltd_pr : public multiwinner_method {
private:
std::vector<std::vector<int> > construct_old_ballots(
const election_t & ballots, int num_candidates) const;
const election_t & ballots, size_t num_candidates) const;

// BEWARE: Pointers!
std::vector<int> QuotaBucklin(
const election_t & ballots,
const std::vector<std::vector<int> > & rankings,
int num_candidates, int council_size, bool hare,
size_t num_candidates, size_t council_size, bool hare,
bool use_card, const std::vector<std::vector<double> > *
rated_ballots) const;

public:
std::list<int> get_council(int council_size, int num_candidates,
std::list<size_t> get_council(size_t council_size, size_t num_candidates,
const election_t & ballots) const;

std::string name() const {
Expand Down
8 changes: 4 additions & 4 deletions src/multiwinner/dhwl.cc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "dhwl.h"

std::list<int> reweighted_condorcet::get_council(int council_size,
int num_candidates, const election_t & ballots) const {
std::list<size_t> reweighted_condorcet::get_council(size_t council_size,
size_t num_candidates, const election_t & ballots) const {

if (council_size > num_candidates) {
throw std::invalid_argument("multiwinner: Too few candidates for the council");
Expand All @@ -12,8 +12,8 @@ std::list<int> reweighted_condorcet::get_council(int council_size,
// in the social order, add him to the council, and set that one as
// elected.

std::list<int> council;
int council_count = 0;
std::list<size_t> council;
size_t council_count = 0;

std::vector<bool> elected(num_candidates, false);

Expand Down
4 changes: 2 additions & 2 deletions src/multiwinner/dhwl.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class reweighted_condorcet : public multiwinner_method {
std::shared_ptr<pairwise_method> base;

public:
std::list<int> get_council(int council_size,
int num_candidates,
std::list<size_t> get_council(size_t council_size,
size_t num_candidates,
const election_t & ballots) const;

std::string name() const {
Expand Down
4 changes: 2 additions & 2 deletions src/multiwinner/dhwl_mat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void DHwLmatrix::add(size_t candidate, size_t against,
}

void DHwLmatrix::count_ballots(const election_t & scores,
int num_candidates) {
size_t num_candidates) {

// See pairwise/matrix.cc

Expand Down Expand Up @@ -113,7 +113,7 @@ void DHwLmatrix::set_elected(size_t elected_idx) {
}

DHwLmatrix::DHwLmatrix(const election_t & scores, const
std::vector<bool> & already_elected, int num_candidates,
std::vector<bool> & already_elected, size_t num_candidates,
pairwise_type type_in, bool tie_at_top, double C_in) : condmat(
type_in) {

Expand Down
4 changes: 2 additions & 2 deletions src/multiwinner/dhwl_mat.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class DHwLmatrix : public condmat {
double deweight(int num_higher_elected_prefs) const;

void count_ballots(const election_t & scores,
int num_candidates);
size_t num_candidates);

void add(size_t candidate, size_t against,
double value);
Expand All @@ -32,6 +32,6 @@ class DHwLmatrix : public condmat {

DHwLmatrix(const election_t & scores,
const std::vector<bool> & already_elected,
int num_candidates, pairwise_type type_in,
size_t num_candidates, pairwise_type type_in,
bool tie_at_top, double C_in);
};
11 changes: 6 additions & 5 deletions src/multiwinner/exhaustive/method.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ template<class T> class exhaustive_method_runner : public
T params_set;

public:
std::list<int> get_council(int council_size,
int num_candidates, const election_t & ballots) const;
std::list<size_t> get_council(size_t council_size,
size_t num_candidates, const election_t & ballots) const;

std::string name() const {
return params_set.name();
Expand All @@ -93,8 +93,9 @@ template<class T> class exhaustive_method_runner : public
}
};

template<class T> std::list<int> exhaustive_method_runner<T>::get_council(
int council_size, int num_candidates,
template<class T> std::list<size_t>
exhaustive_method_runner<T>::get_council(
size_t council_size, size_t num_candidates,
const election_t & ballots) const {

std::vector<size_t> v(num_candidates);
Expand All @@ -113,7 +114,7 @@ template<class T> std::list<int> exhaustive_method_runner<T>::get_council(
exhaustive_optima optimum = for_each_combination(v.begin(),
v.begin() + council_size, v.end(), evaluator);

std::list<int> out;
std::list<size_t> out;

// FIX LATER
for (size_t i: optimum.get_optimal_solution()) {
Expand Down
Loading

0 comments on commit 85d921c

Please sign in to comment.