Snowball implementation (#1)

* Initial test of Snowball implementation

* Add functional plot

* Fix plot

* Remove older duplicate .py file

* Rename glacier-demo.py to snowball-demo.py

* untrack .idea directory

* Add .gitignore file to untrack .idea directory
This commit is contained in:
jessiebroke 2022-07-01 12:56:01 -04:00 committed by GitHub
parent eae4dadb15
commit 8af9267e23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.idea

BIN
README.md

Binary file not shown.

78
snowball-demo.py Normal file
View File

@ -0,0 +1,78 @@
from random import sample
from random import choices
from random import shuffle
import matplotlib.pyplot as plt
import seaborn as sbn
from collections import Counter
# snowball consensus demo - no byzantine
### define parameters
# n: number of participants
n = 400
# k (sample size): between 1 and n | bigger the k the faster the conversion
k = 10
# alpha (quorum size): between 1 and k
alpha = 9
# beta (decision threshold): >= 1
beta = 20
# preference := pizza
# n size list w/ each term n having it's own preference
node_preference = [choices([True, False], weights=[0.55, 0.45])[0] for i in range(n)]
print(Counter(node_preference))
# success counter for each node
node_counter = [0 for i in range(n)]
# node decision
node_decision = [None for i in range(n)]
x_axis = []
while not all(x is not None for x in node_decision): # returns false if any None exist - truthy, any is falsy
indices = [i for i, d in enumerate(node_decision) if d is None]
shuffle(indices)
x_axis.append(Counter(node_preference.copy())) # read up on append command
for node_index in indices:
sample_response = sample(node_preference, k)
print(sample_response)
previous_preference = node_preference[node_index]
# count how many truth
sample_response_count = sample_response.count(previous_preference)
print(sample_response_count)
not_preference_count = len(sample_response)-sample_response_count
# change node decision to align with majority opinion from sampled size
# compare previous node opinion with majority opinion to increment counter if opinion is unchanged
if sample_response_count >= alpha:
node_counter[node_index] += 1
elif not_preference_count >= alpha:
node_counter[node_index] = 1
node_preference[node_index] = not previous_preference
else:
node_counter[node_index] = 0
if node_counter[node_index] > beta:
node_decision[node_index] = node_preference[node_index]
#plot two lines, one w/ yes and one w/ no
yes, no = zip(*((x[True], x[False]) for x in x_axis))
sbn.lineplot(data={"yes": yes, "no": no})
plt.show()
# consecutiveSuccesses := 0
# while not decided:
# ask k random people their preference
# if >= α give the same response:
# preference := response with >= α
# if preference == old preference:
# consecutiveSuccesses++
# else:
# consecutiveSuccesses = 1
# else:
# consecutiveSuccesses = 0
# if consecutiveSuccesses > β:
# decide(preference)