Skip to content

Commit 8c015f1

Browse files
committed
Add decoding and printout to resistant set monotonicity fingerprint class.
1 parent ea85cb2 commit 8c015f1

File tree

1 file changed

+111
-8
lines changed

1 file changed

+111
-8
lines changed

src/design/resistant/monotone.cc

Lines changed: 111 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <stdexcept>
12
#include <iostream>
23
#include <numeric>
34
#include <vector>
@@ -33,39 +34,66 @@ typedef std::vector<size_t>::const_iterator it;
3334
class subelections {
3435
private:
3536
bool add_subelection(combo::it begin, combo::it end);
37+
size_t numcands;
3638

3739
public:
3840
std::vector<std::vector<size_t> > subelection_members;
39-
std::vector<size_t> max_options;
40-
subelections(size_t numcands);
41+
std::vector<std::vector<bool> > is_subelection_member;
42+
43+
std::vector<size_t> num_options;
44+
size_t distinct_fingerprints;
45+
46+
subelections(size_t numcands_in);
4147

4248
size_t get_num_fingerprint_indices() const;
4349
};
4450

4551
bool subelections::add_subelection(combo::it begin, combo::it end) {
4652
subelection_members.push_back(std::vector<size_t>(begin, end));
4753
size_t num_members = end-begin;
48-
max_options.push_back((1<<num_members) - 2);
54+
num_options.push_back((1<<num_members) - 2);
55+
56+
// Also add a vector where is_member[x] is true if the xth
57+
// candidate is a part of this subelection.
58+
std::vector<bool> is_member(numcands, false);
59+
60+
for (combo::it pos = begin; pos != end; ++pos) {
61+
is_member[*pos] = true;
62+
}
4963

5064
return false;
5165
}
5266

53-
subelections::subelections(size_t numcands) {
67+
subelections::subelections(size_t numcands_in) {
68+
69+
numcands = numcands_in;
70+
71+
size_t i;
5472

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

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

6684
for_each_combination(cands.begin(), cands.begin() + i,
6785
cands.end(), this_add_subelection);
6886
}
87+
88+
// Calculate the number of distinct fingerprints
89+
// based on the number of subelections and the number
90+
// of ways candidates can be chosen within each.
91+
92+
distinct_fingerprints = 1;
93+
94+
for (i = 0; i < num_options.size(); ++i) {
95+
distinct_fingerprints *= num_options[i];
96+
}
6997
}
7098

7199

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

83-
void decode(size_t index);
111+
void decode(const subelections & se, size_t index);
84112
size_t encode() const;
113+
void print(const subelections & se) const;
85114
};
86115

87-
int main() {
116+
void fingerprint::decode(const subelections & se, size_t index) {
88117

89-
size_t numcands = 3;
118+
if (index >= se.distinct_fingerprints) {
119+
throw std::invalid_argument("index exceeds number of fingerprints!");
120+
}
121+
122+
for (size_t subelec_idx = 0; subelec_idx < se.num_options.size();
123+
++subelec_idx) {
124+
// Get the index to apply to this particular subelection.
125+
size_t num_options = se.num_options[subelec_idx];
126+
size_t digit = index % num_options;
127+
128+
// Then decode it.
129+
size_t num_members = se.subelection_members[subelec_idx].size();
130+
std::vector<size_t> candidates_above_quota;
131+
132+
// Since at least one candidate must exceed the quota,
133+
// an index of zero, which would correspond to an all-false
134+
// vector, is disallowed.
135+
++digit;
136+
137+
for (size_t member_idx = 0; member_idx < num_members; ++member_idx) {
138+
if (digit % 2 == 1) {
139+
candidates_above_quota.push_back(
140+
se.subelection_members[subelec_idx][member_idx]);
141+
}
142+
digit >>= 1;
143+
}
144+
145+
above_quota.push_back(candidates_above_quota);
146+
147+
std::cout << digit << " of " << num_options << "\n";
148+
index /= num_options;
149+
}
150+
}
90151

152+
void fingerprint::print(const subelections & se) const {
153+
size_t i;
154+
155+
for (size_t subelec_idx = 0; subelec_idx < se.num_options.size();
156+
++subelec_idx) {
157+
158+
std::cout << "Subelection {";
159+
160+
for (i = 0; i < se.subelection_members[subelec_idx].size();
161+
++i) {
162+
if (i != 0) {
163+
std::cout << ", ";
164+
}
165+
std::cout << (char)('A' + se.subelection_members[
166+
subelec_idx][i]);
167+
}
168+
169+
std::cout << "}: above quota: ";
170+
171+
for (i = 0; i < above_quota[subelec_idx].size(); ++i) {
172+
if (i != 0) {
173+
std::cout << ", ";
174+
}
175+
176+
std::cout << (char)('A' + above_quota[subelec_idx][i]);
177+
}
178+
179+
std::cout << "\n";
180+
}
181+
}
182+
183+
int main() {
184+
185+
size_t numcands = 4;
91186
subelections se(numcands);
92187

188+
fingerprint test;
189+
190+
std::cout << "Number of distinct fingerprints: "
191+
<< se.distinct_fingerprints << "\n";
192+
193+
test.decode(se, 19001);
194+
test.print(se);
195+
93196
return 0;
94197
}

0 commit comments

Comments
 (0)