Skip to content

Commit

Permalink
Add decoding and printout to resistant set monotonicity fingerprint c…
Browse files Browse the repository at this point in the history
…lass.
  • Loading branch information
kristomu committed Feb 9, 2025
1 parent ea85cb2 commit 8c015f1
Showing 1 changed file with 111 additions and 8 deletions.
119 changes: 111 additions & 8 deletions src/design/resistant/monotone.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <stdexcept>
#include <iostream>
#include <numeric>
#include <vector>
Expand Down Expand Up @@ -33,39 +34,66 @@ typedef std::vector<size_t>::const_iterator it;
class subelections {
private:
bool add_subelection(combo::it begin, combo::it end);
size_t numcands;

public:
std::vector<std::vector<size_t> > subelection_members;
std::vector<size_t> max_options;
subelections(size_t numcands);
std::vector<std::vector<bool> > is_subelection_member;

std::vector<size_t> num_options;
size_t distinct_fingerprints;

subelections(size_t numcands_in);

size_t get_num_fingerprint_indices() const;
};

bool subelections::add_subelection(combo::it begin, combo::it end) {
subelection_members.push_back(std::vector<size_t>(begin, end));
size_t num_members = end-begin;
max_options.push_back((1<<num_members) - 2);
num_options.push_back((1<<num_members) - 2);

// Also add a vector where is_member[x] is true if the xth
// candidate is a part of this subelection.
std::vector<bool> is_member(numcands, false);

for (combo::it pos = begin; pos != end; ++pos) {
is_member[*pos] = true;
}

return false;
}

subelections::subelections(size_t numcands) {
subelections::subelections(size_t numcands_in) {

numcands = numcands_in;

size_t i;

// Curry the implicit reference to the calling object.
auto this_add_subelection = [this](combo::it begin,
combo::it end) {
return add_subelection(begin, end);
};

for (size_t i = 2; i <= numcands; ++i) {
for (i = 2; i <= numcands; ++i) {
// Add every sub-election of i candidates.
std::vector<size_t> cands(numcands, 0);
std::iota(cands.begin(), cands.end(), 0);

for_each_combination(cands.begin(), cands.begin() + i,
cands.end(), this_add_subelection);
}

// Calculate the number of distinct fingerprints
// based on the number of subelections and the number
// of ways candidates can be chosen within each.

distinct_fingerprints = 1;

for (i = 0; i < num_options.size(); ++i) {
distinct_fingerprints *= num_options[i];
}
}


Expand All @@ -80,15 +108,90 @@ class fingerprint {
public:
std::vector<std::vector<size_t> > above_quota;

void decode(size_t index);
void decode(const subelections & se, size_t index);
size_t encode() const;
void print(const subelections & se) const;
};

int main() {
void fingerprint::decode(const subelections & se, size_t index) {

size_t numcands = 3;
if (index >= se.distinct_fingerprints) {
throw std::invalid_argument("index exceeds number of fingerprints!");
}

for (size_t subelec_idx = 0; subelec_idx < se.num_options.size();
++subelec_idx) {
// Get the index to apply to this particular subelection.
size_t num_options = se.num_options[subelec_idx];
size_t digit = index % num_options;

// Then decode it.
size_t num_members = se.subelection_members[subelec_idx].size();
std::vector<size_t> candidates_above_quota;

// Since at least one candidate must exceed the quota,
// an index of zero, which would correspond to an all-false
// vector, is disallowed.
++digit;

for (size_t member_idx = 0; member_idx < num_members; ++member_idx) {
if (digit % 2 == 1) {
candidates_above_quota.push_back(
se.subelection_members[subelec_idx][member_idx]);
}
digit >>= 1;
}

above_quota.push_back(candidates_above_quota);

std::cout << digit << " of " << num_options << "\n";
index /= num_options;
}
}

void fingerprint::print(const subelections & se) const {
size_t i;

for (size_t subelec_idx = 0; subelec_idx < se.num_options.size();
++subelec_idx) {

std::cout << "Subelection {";

for (i = 0; i < se.subelection_members[subelec_idx].size();
++i) {
if (i != 0) {
std::cout << ", ";
}
std::cout << (char)('A' + se.subelection_members[
subelec_idx][i]);
}

std::cout << "}: above quota: ";

for (i = 0; i < above_quota[subelec_idx].size(); ++i) {
if (i != 0) {
std::cout << ", ";
}

std::cout << (char)('A' + above_quota[subelec_idx][i]);
}

std::cout << "\n";
}
}

int main() {

size_t numcands = 4;
subelections se(numcands);

fingerprint test;

std::cout << "Number of distinct fingerprints: "
<< se.distinct_fingerprints << "\n";

test.decode(se, 19001);
test.print(se);

return 0;
}

0 comments on commit 8c015f1

Please sign in to comment.