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:
parent
eae4dadb15
commit
8af9267e23
|
@ -0,0 +1 @@
|
|||
.idea
|
|
@ -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)
|
Loading…
Reference in New Issue