Skip to content

Instantly share code, notes, and snippets.

@yohm
Created December 30, 2020 08:07
Show Gist options
  • Save yohm/78d4ad49f471bf24a968e0ac8925eebf to your computer and use it in GitHub Desktop.
Save yohm/78d4ad49f471bf24a968e0ac8925eebf to your computer and use it in GitHub Desktop.
#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