aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAiden Woodruff <woodra@rpi.edu>2025-11-03 10:50:43 -0500
committerAiden Woodruff <woodra@rpi.edu>2025-11-03 10:50:43 -0500
commitc4b6d2dad64b8136b99fa7358ec141d4a46ff4e9 (patch)
treefcb85d496c563131a917c6b8c840a9ff6fd16e26
parent7a4dc603584fdb12fd828de2729986b5eb92a1aa (diff)
downloadtipping-points-c4b6d2dad64b8136b99fa7358ec141d4a46ff4e9.tar.gz
tipping-points-c4b6d2dad64b8136b99fa7358ec141d4a46ff4e9.tar.bz2
tipping-points-c4b6d2dad64b8136b99fa7358ec141d4a46ff4e9.zip
add code for onr round of name game
Signed-off-by: Aiden Woodruff <woodra@rpi.edu>
-rw-r--r--src/main.cc92
1 files changed, 78 insertions, 14 deletions
diff --git a/src/main.cc b/src/main.cc
index 467c1ad..0f391eb 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -1,12 +1,17 @@
1#include <cassert> 1#include <cassert>
2#include <iostream> 2#include <iostream>
3#include <map>
3#include <random> 4#include <random>
4 5
5#include <Snap.h> 6#include <Snap.h>
6 7
7void name_game(int group_size, int cmsize); 8void name_game(int group_size, int cmsize);
8 9
10constexpr int memory_length = 12;
11std::mt19937 rng(std::random_device{}());
12
9int main(int argc, char* argv[]) { 13int main(int argc, char* argv[]) {
14 rng.seed(std::random_device{}());
10 int group_size = 100; 15 int group_size = 100;
11 for (int cmperc = 18; cmperc < 28; cmperc += 2) { 16 for (int cmperc = 18; cmperc < 28; cmperc += 2) {
12 int cmsize = group_size * cmperc / 100; 17 int cmsize = group_size * cmperc / 100;
@@ -16,40 +21,99 @@ int main(int argc, char* argv[]) {
16 return 0; 21 return 0;
17} 22}
18 23
19// SNAP random chooses node, r is used to select one edge 24using ngData = TPair<TBool, TIntV>;
20template <typename TD> 25
21typename TNodeNet<TD>::TEdgeI random_edge(const TNodeNet<TD>& g, int r) { 26template<typename TVal, typename TSizeTy>
22 auto ni = g.GetRndNI(); 27auto begin(const TVec<TVal, TSizeTy>& v) -> decltype(v.BegI()) {
23 return g.GetEI(ni.GetId(), ni.GetNbrNId(r % ni.GetDeg())); 28 return v.BegI();
29}
30
31template<typename TVal, typename TSizeTy>
32auto end(const TVec<TVal, TSizeTy>& v) -> decltype(v.EndI()) {
33 return v.EndI();
34}
35
36int best_move(const ngData& d) {
37 const auto& mem = d.Val2;
38 std::map<int, int> votes;
39 for (const auto& v : mem) {
40 if (votes.count(v)) votes[v] += 1;
41 else votes[v] = 1;
42 }
43 std::map<int, float> fractions;
44 for (auto kv : votes) fractions[kv.first] = kv.second * 1./mem.Len();
45 // Simple majority vote:
46 for (auto kv : fractions)
47 if (kv.second >= 1./mem.Len()) return kv.first;
48 return 0;
49}
50
51void update_memory(ngData& d, int move) {
52 if (!d.Val1) {
53 auto& mem = d.Val2;
54 mem.Ins(0, move);
55 mem.Trunc(memory_length);
56 }
57}
58
59void name_game_round(TNodeNet<ngData>& graph) {
60 std::uniform_int_distribution<> dist(0, graph.GetNodes());
61 // Select random speaker and hearer.
62 auto speaker = graph.GetNI(dist(rng));
63 auto hearer = graph.GetNI(
64 speaker.GetNbrNId(dist(rng) % speaker.GetDeg())
65 );
66
67 // Speaker chooses best strategy.
68 int s_strategy = best_move(speaker.GetDat());
69 std::cout << "speaker (" << speaker.GetId() << " "
70 << std::boolalpha << speaker().Val1
71 << ") chose: " << s_strategy << std::endl;
72
73 // Listener updates memory.
74 update_memory(hearer.GetDat(), s_strategy);
75
76 // Listener chooses best strategy.
77 int h_strategy = best_move(hearer.GetDat());
78 std::cout << "hearer (" << hearer.GetId() << " "
79 << std::boolalpha << hearer().Val1
80 << ") chose: " << h_strategy << std::endl;
81
82 // Speaker updates memory.
83 update_memory(speaker.GetDat(), s_strategy);
24} 84}
25 85
26void name_game(int group_size, int cmsize) { 86void name_game(int group_size, int cmsize) {
27 assert(cmsize > 0 && group_size > 0); 87 assert(cmsize > 0 && group_size > 0);
28 assert(cmsize < group_size); 88 assert(cmsize < group_size);
29 TNodeNet<TPair<TBool, TIntV>> graph; 89 TNodeNet<ngData> graph;
30 // Generate complete graph. 90 // Generate complete graph.
31 for (int i = 0; i < group_size; ++i) graph.AddNode(i, {false, {}}); 91 for (int i = 0; i < group_size; ++i) graph.AddNode(i, {false, {}});
32 for (int i = 0; i < group_size; ++i) 92 for (int i = 0; i < group_size; ++i)
33 for (int j = 0; j < group_size; ++j) 93 for (int j = 0; j < group_size; ++j)
34 if (i != j) graph.AddEdge(i, j); 94 if (i != j) graph.AddEdge(i, j);
35 // Set committed minority. 95 // Set committed minority.
36 std::mt19937 rnd(std::random_device{}()); 96 std::uniform_int_distribution<> dist(0, group_size - 1);
37 std::uniform_int_distribution dist(0, group_size - 1);
38 for (int i = 0; i < cmsize;) { 97 for (int i = 0; i < cmsize;) {
39 int r = dist(rnd); 98 int r = dist(rng);
40 if (!graph.GetNDat(r).Val1) { 99 if (!graph.GetNDat(r).Val1) {
41 graph.GetNDat(r).Val1 = true; 100 graph.GetNDat(r).Val1 = true;
101 auto& mem = graph.GetNDat(r).Val2;
102 mem.Clr();
103 mem.Add(2);
42 ++i; 104 ++i;
43 } 105 }
44 } 106 }
107 // Establish norm (fully memory of strategy 1)
108 for (int i = 0; i < group_size; ++i) {
109 auto& d = graph.GetNDat(i);
110 if (!d.Val1) while (d.Val2.Len() < memory_length) d.Val2.Add(1);
111 }
45 std::cout << "Nodes: " << graph.GetNodes() 112 std::cout << "Nodes: " << graph.GetNodes()
46 << " Edges: " << graph.GetEdges() << std::endl; 113 << " Edges: " << graph.GetEdges() << std::endl;
47 114
48 // Select random edge. 115 name_game_round(graph);
49 // Speaker chooses best strategy. 116
50 // Listener updates memory.
51 // Listener chooses best strategy.
52 // Speaker updates memory.
53 // Track all plays and plays by non-CM. 117 // Track all plays and plays by non-CM.
54 // Report average plays. 118 // Report average plays.
55} 119}