From 8af9267e231ec03a65da257940afa62b9c7e7a8b Mon Sep 17 00:00:00 2001 From: jessiebroke <18238304+jessiebroke@users.noreply.github.com> Date: Fri, 1 Jul 2022 12:56:01 -0400 Subject: [PATCH] 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 --- .gitignore | 1 + README.md | Bin 66 -> 110 bytes snowball-demo.py | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 .gitignore create mode 100644 snowball-demo.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/README.md b/README.md index 283dc8e8a5513251b86d04c0c557e17b26f2deab..93be039ebbe338059aefd8f2c9bf7ca17f4cd3cc 100644 GIT binary patch delta 81 zcmZ?Do1o;w%fQ9p$&kxXz>vd`3ZzpR@)$}O5`j3AAs@(A0Fr4yG8o9tXDDY#0?Oq8 Sp#o4IBpbj`2~?W_Rto@(-w%8M literal 66 qcmezWPnki1A)O(IA(0`OA(J7Mp@>13Aq7b1GUPMxGH@{vk_Q0Nc?<*q diff --git a/snowball-demo.py b/snowball-demo.py new file mode 100644 index 0000000..ca8b58f --- /dev/null +++ b/snowball-demo.py @@ -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) \ No newline at end of file