-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Bernoulli generator and binary issue space PR measure.
This replicates the old multiwinner functionality (though still without the VSE rescaling). I'll need to get the VSE stuff going before I can test it against the old implementation. multiwinner.cc shows how to generate and test binary issue spaces.
- Loading branch information
Showing
7 changed files
with
185 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
|
||
// All spatial utility generators. | ||
|
||
#include "bernoulli.h" | ||
#include "gaussian.h" | ||
#include "spatial.h" | ||
#include "uniform.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#include "bernoulli.h" | ||
#include <vector> | ||
|
||
std::vector<double> bernoulli_generator::rnd_vector(size_t size, | ||
coordinate_gen & coord_source) const { | ||
|
||
std::vector<double> coord = coord_source.get_coordinate( | ||
size); | ||
|
||
// Clamp. | ||
for (size_t i = 0; i < size; ++i) { | ||
if (coord[i] <= center[i]) { | ||
coord[i] = 1; | ||
} else { | ||
coord[i] = 0; | ||
} | ||
} | ||
|
||
return coord; | ||
} | ||
|
||
void bernoulli_generator::bias_generator(size_t num_dimensions, | ||
coordinate_gen & coord_source) { | ||
|
||
set_center(coord_source.get_coordinate( | ||
num_dimensions)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// n-dimensional Bernoulli distribution: each coordinate is true (one) | ||
// with probability p and false (zero) with probability (1-p). The center | ||
// (location) variable is a vector of these p, because expected value on | ||
// each axis is p. | ||
|
||
#pragma once | ||
#include "spatial.h" | ||
|
||
class bernoulli_generator : public spatial_generator { | ||
protected: | ||
std::vector<double> rnd_vector(size_t size, | ||
coordinate_gen & coord_source) const; | ||
|
||
public: | ||
bernoulli_generator() : spatial_generator() { | ||
uses_center = true; | ||
uses_dispersion = false; | ||
set_center(0.5); | ||
} | ||
bernoulli_generator(bool compress_in) : spatial_generator( | ||
compress_in) { | ||
uses_center = true; | ||
uses_dispersion = false; | ||
set_center(0.5); | ||
} | ||
bernoulli_generator(bool compress_in, bool do_truncate) | ||
: spatial_generator(compress_in, do_truncate) { | ||
uses_center = true; | ||
uses_dispersion = false; | ||
set_center(0.5); | ||
} | ||
|
||
bernoulli_generator(bool compress_in, bool do_truncate, | ||
double num_dimensions_in, bool warren_util_in) : | ||
spatial_generator(compress_in, do_truncate, | ||
num_dimensions_in, warren_util_in) { | ||
uses_center = true; uses_dispersion = false; | ||
set_center(0.5); | ||
} | ||
|
||
// Sets the centers to random values between 0 and 1, | ||
// with the given number of dimensions. Used for binary issue | ||
// testing. | ||
void bias_generator(size_t num_dimensions, | ||
coordinate_gen & coord_source); | ||
|
||
std::string name() const { | ||
return ("Bernoulli"); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#include "binary.h" | ||
|
||
#include "multiwinner/helper/errors.h" | ||
|
||
void binary_proportionality::prepare(const positions_election & p_e) { | ||
|
||
size_t num_voters = p_e.voters_pos.size(), | ||
num_issues = p_e.voters_pos[0].size(); | ||
|
||
issue_voter_proportions.resize(num_issues); | ||
issue_winner_proportions.resize(num_issues); | ||
|
||
std::fill(issue_voter_proportions.begin(), | ||
issue_voter_proportions.end(), 0.0); | ||
|
||
candidate_opinions = p_e.candidates_pos; | ||
|
||
for (size_t voter = 0; voter < num_voters; ++voter) { | ||
for (size_t issue = 0; issue < num_issues; ++issue) { | ||
if (p_e.voters_pos[voter][issue] != 0 && | ||
p_e.voters_pos[voter][issue] != 1) { | ||
// Maybe use sign value here to generalize to any | ||
// distribution??? Would that be too confusing? | ||
// Would it be helpful? Nah, that would make Bernoulli | ||
// fail -- silently. Probably not a good idea. | ||
throw std::invalid_argument("Binary proportionality: voter" | ||
" issue vectors aren't binary!"); | ||
} | ||
if (p_e.voters_pos[voter][issue] == 1) { | ||
issue_voter_proportions[issue] += 1.0/num_voters; | ||
} | ||
} | ||
} | ||
} | ||
|
||
double binary_proportionality::get_error( | ||
const std::list<size_t> & outcome) { | ||
|
||
size_t num_seats = outcome.size(), | ||
num_issues = issue_winner_proportions.size(); | ||
|
||
std::fill(issue_winner_proportions.begin(), | ||
issue_winner_proportions.end(), 0.0); | ||
|
||
for (size_t winner: outcome) { | ||
for (size_t issue = 0; issue < num_issues; ++issue) { | ||
if (candidate_opinions[winner][issue] != 0 && | ||
candidate_opinions[winner][issue] != 1) { | ||
// Maybe use sign value here to generalize to any | ||
// distribution??? Would that be too confusing? | ||
// Would it be helpful? Nah, that would make Bernoulli | ||
// fail -- silently. Probably not a good idea. | ||
throw std::invalid_argument("Binary proportionality: winner" | ||
" issue vectors aren't binary!"); | ||
} | ||
if (candidate_opinions[winner][issue] == 1) { | ||
issue_winner_proportions[issue] += 1.0/num_seats; | ||
} | ||
} | ||
} | ||
|
||
return sli(issue_winner_proportions, | ||
issue_voter_proportions); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#include "measure.h" | ||
#include <vector> | ||
|
||
// This proportionality measure only works on binary spatial models, but | ||
// is pretty simple. It just checks the proportion of the voters that | ||
// agree with each issue (take the true or 1 position) and compares this | ||
// to the proportion of the winners that do. | ||
|
||
// TODO? Maybe a print function??? | ||
|
||
class binary_proportionality : public proportionality_measure { | ||
private: | ||
// These vectors ought to be bool but because all spatial | ||
// generators work on double, we use what we're given. | ||
|
||
// Each candidate's opinion (true = 1, false = 0) on | ||
// every issue. | ||
std::vector<std::vector<double> > candidate_opinions; | ||
|
||
// The fraction of voters and winners who take the true | ||
// position on each issue. | ||
std::vector<double> issue_voter_proportions; | ||
std::vector<double> issue_winner_proportions; | ||
|
||
public: | ||
void prepare(const positions_election & p_e); | ||
double get_error(const std::list<size_t> & outcome); | ||
}; |