Created
December 30, 2020 08:07
-
-
Save yohm/78d4ad49f471bf24a968e0ac8925eebf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <random> | |
#include <array> | |
// Cooperate : 1, Defect : 0 | |
// Good : 1, Bad : 0 | |
class AssessmentRule { | |
public: | |
AssessmentRule(size_t _id = 0) : id(_id) { assert(id >= 0 && id < 256); }; | |
size_t Assess(size_t action, size_t rep_d, size_t rep_r) const { | |
assert(rep_d == 0 || rep_d == 1); | |
assert(rep_r == 0 || rep_r == 1); | |
assert(action == 0 || action == 1); | |
size_t i = action * 4 + rep_d * 2 + rep_r; | |
return (id >> i) & 1ul; | |
} | |
size_t id; | |
}; | |
class ActionRule { | |
public: | |
ActionRule(size_t _id = 0) : id(_id) { assert(id >= 0 && id < 16); } | |
size_t Action(size_t rep_d, size_t rep_r) { | |
assert(rep_d == 0 || rep_d == 1); | |
assert(rep_r == 0 || rep_r == 1); | |
size_t i = rep_d * 2 + rep_r; | |
return (id >> i) & 1ul; | |
} | |
size_t id; | |
}; | |
class Game { // population with focal strategy, AllC, AllD | |
public: | |
Game(size_t _N, AssessmentRule as_rule, ActionRule ac_rule, uint64_t _seed) : N(_N), seed(_seed), as(as_rule), ac(ac_rule), rnd(_seed), uni(0.0, 1.0) { | |
assessment_rules.resize(N); | |
action_rules.resize(N); | |
M.resize(N); | |
for (size_t i = 0; i < N; i++) { M[i].resize(N); } | |
for (size_t i = 0; i < N/3; i++) { | |
assessment_rules[i] = as_rule; | |
action_rules[i] = ac_rule; | |
} | |
for (size_t i = N/3; i < N*2/3; i++) { | |
assessment_rules[i].id = 0b11111111; // AllC | |
action_rules[i].id = 0b1111; | |
} | |
for (size_t i = N*2/3; i < N; i++) { | |
assessment_rules[i].id = 0b00000000; // AllD | |
action_rules[i].id = 0b0000; | |
} | |
for (size_t i = 0; i < N; i++) { | |
for (size_t j = 0; j < N; j++) { | |
M[i][j] = 1; // initialize with Good reputation | |
} | |
} | |
} | |
void Update(size_t t_max, double q, double epsilon) { | |
for (size_t t = 0; t < t_max; t++) { | |
// randomly choose donor & recipient | |
size_t donor = static_cast<size_t>(R01() * N); | |
size_t recip = static_cast<size_t>(R01() * N); | |
while (recip == donor) { recip = static_cast<size_t>(R01() * N); } | |
size_t action = action_rules[donor].Action( M[donor][donor], M[donor][recip] ); | |
// updating the donor's reputation | |
for (size_t obs = 0; obs < N; obs++) { | |
if (obs == donor || obs == recip || R01() < q) { // observe with probability q | |
size_t a_obs = (R01() < 1.0 - epsilon) ? action : (action^1ul); | |
size_t assessment = assessment_rules[obs].Assess(a_obs, M[obs][donor], M[obs][recip]); | |
M[obs][donor] = assessment; | |
} | |
} | |
} | |
} | |
std::array<size_t,3> NumGood() { | |
std::array<size_t,3> ans = {0}; | |
for (size_t i = 0; i < N/3; i++) { | |
for (size_t j = 0; j < N/3; j++) { | |
ans[0] += M[i][j]; | |
} | |
for (size_t j = N/3; j < N*2/3; j++) { | |
ans[1] += M[i][j]; | |
} | |
for (size_t j = N*2/3; j < N; j++) { | |
ans[2] += M[i][j]; | |
} | |
} | |
return std::move(ans); | |
} | |
void Print(std::ostream & out) { | |
for (size_t i = 0; i < N/3; i++) { | |
for (size_t j = 0; j < N; j++) { | |
if (j == N/3 || j == 2*N/3) { out << '|'; } | |
char c = (M[i][j] == 0) ? ' ' : '*'; | |
out << c; | |
} | |
out << std::endl; | |
} | |
} | |
size_t N; | |
AssessmentRule as; | |
ActionRule ac; | |
uint64_t seed; | |
std::mt19937_64 rnd; | |
std::uniform_real_distribution<double> uni; | |
std::vector<std::vector<size_t> > M; | |
std::vector<AssessmentRule> assessment_rules; | |
std::vector<ActionRule> action_rules; | |
double R01() { return uni(rnd); } | |
}; | |
void Simulate(const AssessmentRule & as_rule, const ActionRule & ac_rule) { | |
const size_t N = 90; | |
Game g(N, as_rule, ac_rule, 1234ul); | |
g.Update(10000, 0.9, 0.05); | |
std::array<size_t,3> counts = {0}; | |
const size_t N_measure = 100; | |
for (size_t i = 0; i < N_measure; i++) { | |
g.Update(100, 0.9, 0.05); | |
auto c = g.NumGood(); | |
counts[0] += c[0]; | |
counts[1] += c[1]; | |
counts[2] += c[2]; | |
} | |
std::cout << static_cast<double>(counts[0])/(N_measure * N*N / 9) << ' ' | |
<< static_cast<double>(counts[1])/(N_measure * N*N / 9) << ' ' | |
<< static_cast<double>(counts[2])/(N_measure * N*N / 9) << std::endl; | |
// g.Print(std::cout); | |
} | |
int main(int argc, char* argv[]) { | |
const size_t L1_as = 0b11110100, L1_ac = 0b1011; | |
const size_t L2_as = 0b10110100, L2_ac = 0b1011; | |
const size_t L3_as = 0b11110101, L3_ac = 0b1010; | |
const size_t L4_as = 0b11100101, L4_ac = 0b1010; | |
const size_t L5_as = 0b10110101, L5_ac = 0b1010; | |
const size_t L6_as = 0b10100101, L6_ac = 0b1010; | |
const size_t L7_as = 0b11100100, L7_ac = 0b1010; | |
const size_t L8_as = 0b10100100, L8_ac = 0b1010; | |
{ | |
std::cout << "L1:" << std::endl; | |
AssessmentRule as_rule(L1_as); | |
ActionRule ac_rule(L1_ac); | |
Simulate(as_rule, ac_rule); | |
} | |
{ | |
std::cout << "L2:" << std::endl; | |
AssessmentRule as_rule(L2_as); | |
ActionRule ac_rule(L2_ac); | |
Simulate(as_rule, ac_rule); | |
} | |
{ | |
std::cout << "L3:" << std::endl; | |
AssessmentRule as_rule(L3_as); | |
ActionRule ac_rule(L3_ac); | |
Simulate(as_rule, ac_rule); | |
} | |
{ | |
std::cout << "L4:" << std::endl; | |
AssessmentRule as_rule(L4_as); | |
ActionRule ac_rule(L4_ac); | |
Simulate(as_rule, ac_rule); | |
} | |
{ | |
std::cout << "L5:" << std::endl; | |
AssessmentRule as_rule(L5_as); | |
ActionRule ac_rule(L5_ac); | |
Simulate(as_rule, ac_rule); | |
} | |
{ | |
std::cout << "L6:" << std::endl; | |
AssessmentRule as_rule(L6_as); | |
ActionRule ac_rule(L6_ac); | |
Simulate(as_rule, ac_rule); | |
} | |
{ | |
std::cout << "L7:" << std::endl; | |
AssessmentRule as_rule(L7_as); | |
ActionRule ac_rule(L7_ac); | |
Simulate(as_rule, ac_rule); | |
} | |
{ | |
std::cout << "L8:" << std::endl; | |
AssessmentRule as_rule(L8_as); | |
ActionRule ac_rule(L8_ac); | |
Simulate(as_rule, ac_rule); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment