pgg2Punishments.java
/* ********** ゲームの定義 **************** */
public class pgg2Punishments {
class parameters {
double r, gamma, beta, m, gamma_m, K;
}
public static parameters param;
public int [][] s;
static int size;
/* コンストラクタ */
pgg2Punishments(int givenSize) {
param = new parameters();
size = givenSize;
s = new int [size][size];
}
/* 係数の設定 */
public void setParameters(double gamma,double beta,double r, double K, double m) {
param.gamma =gamma;
param.beta = beta;
param.r = r;
param.K = K;
param.m = m;
param.gamma_m = gamma*m;
}
/* ランダムパターンに初期化 */
public void initializePlayers() {
int i, j;
// initialize array of players:
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
this.s[i][j] = (int) (Math.random()*4.0);
}
}
}
/* ****************************************************
* 1ステップ
* *****************************************************
*/
public boolean update_strategy(int i, int j) {
double diffPayoff;
int neighbor_i, neighbor_j;
if(Math.random() < 0.5) {
neighbor_j = j;
if(Math.random()<0.5)
neighbor_i = plus_neighbor(i);
else
neighbor_i = minus_neighbor(i);
} else {
neighbor_i=i;
if(Math.random() <0.5)
neighbor_j = minus_neighbor(j);
else
neighbor_j = plus_neighbor(j);
}
diffPayoff = calcPayoff(i,j) - calcPayoff(neighbor_i,neighbor_j);
if(Math.random() < 1.0 / (1.0 + Math.exp(diffPayoff / param.K))) {
this.s[i][j] = this.s[neighbor_i][neighbor_j];
return true;
}
else return false;
}
/* ****************************
* 隣の格子番号を返す(境界条件)
* ****************************
*/
public static int plus_neighbor(int i) {
if(i==size-1) return 0;
else return i+1;
}
public static int minus_neighbor(int i) {
if(i==0) return size-1;
else return i-1;
}
/* ****************************
* payoffの計算
* *****************************
*/
/* (i,j)とその周辺を中心とする5つのゲームのpayoffの総和 */
public double calcPayoff(int i, int j) {
return calcPayoffInSingleGame(i,j,this.s[i][j]) +
calcPayoffInSingleGame(plus_neighbor(i),j,this.s[i][j]) +
calcPayoffInSingleGame(minus_neighbor(i),j,this.s[i][j]) +
calcPayoffInSingleGame(i,plus_neighbor(j),this.s[i][j]) +
calcPayoffInSingleGame(i,minus_neighbor(j),this.s[i][j]);
}
/* (i,j)を中心とする1つのゲームでの、my_strategyに関するpayoffを計算 */
public double calcPayoffInSingleGame(int i, int j, int my_strategy) {
double invest, n_d, n_e, f_o;
/* invest: C,O,Eの総数, n_d, n_e: D, Eの数, f_o: Oの数の階段関数 */
int right, left, top, bottom;
// 左右上下の格子番号取得
left = minus_neighbor(i);
right = plus_neighbor(i);
bottom = minus_neighbor(j);
top = plus_neighbor(j);
/* payoff の計算 */
invest = 0.0;
n_e = 0.0;
f_o = 0.0;
if (this.s[i][j] != 0) { // Dでなかったら
invest += 1.0;
if (this.s[i][j] == 2)
f_o = 1.0; // pool punisherの場合
else if (this.s[i][j] == 1)
n_e += 1.0; // peer punisherの場合
}
if (this.s[right][j] != 0) {
invest += 1.0;
if (this.s[right][j] == 2)
f_o = 1.0;
else if (this.s[right][j] == 1)
n_e += 1.0;
}
if (this.s[left][j] != 0) {
invest += 1.0;
if (this.s[left][j] == 2)
f_o = 1.0;
else if (this.s[left][j] == 1)
n_e += 1.0;
}
if (this.s[i][top] != 0) {
invest += 1.0;
if (this.s[i][top] == 2)
f_o = 1.0;
else if (this.s[i][top] == 1)
n_e += 1.0;
}
if (this.s[i][bottom] != 0) {
invest += 1.0;
if (this.s[i][bottom] == 2)
f_o = 1.0;
else if (this.s[i][bottom] == 1)
n_e += 1.0;
}
n_d = 5.0 - invest;
if (my_strategy == 3) { // cooperator
return param.r * invest / 5.0 - 1.0;
} else if (my_strategy == 2) { // pool punisher
return param.r * invest / 5.0 - 1.0 - param.gamma;
} else if (my_strategy == 1) { // peer punisher
return param.r * invest / 5.0 - 1.0 - param.gamma_m * n_d;
} else if (my_strategy == 0) { // defector
return param.r * invest / 5.0 - param.beta * (param.m * n_e + f_o);
} else { // エラー
// System.out.println(i+j);
return 100.0;
}
}
}