selkie01.gms : SELKIE test suite

Description

Tragedy of the Commons:

Each agent i sends x(i) units of flow along the shared channel with capacity 1.
The value of each agent by sending x(i) units is x(i)*(1 - sum(j, x(j))).
Then each agent tries to solve the following:

   maximize_{x(i)}    x(i)*(1 - sum(j, x(j)))
   suject to
                      sum(j, x(j)) <= 1
                      0 <= x(i) <= 1

There is a unique equilibrium solution x(i) = 1/(N+1). Then

   The value for each player: 1/(N+1)^2
   The total value          : N/(N+1)^2 \approx 1/N

The equilibrium is obtained when all agents are playing their optimal selfish
strategy. However, if agents cooperate in a way that the total flow
sum(i, x(i)) is 1/2, then the total value is 1/4, which could be much larger
than 1/N for large enough N. This is called the tragedy of the commons.

Contributor: Youngdae Kim, Dec 2016


Small Model of Type : GAMS


Category : GAMS Test library


Main file : selkie01.gms

$title 'SELKIE test suite'  (SELKIE01,SEQ=757)

$ontext

Tragedy of the Commons:

Each agent i sends x(i) units of flow along the shared channel with capacity 1.
The value of each agent by sending x(i) units is x(i)*(1 - sum(j, x(j))).
Then each agent tries to solve the following:

   maximize_{x(i)}    x(i)*(1 - sum(j, x(j)))
   suject to
                      sum(j, x(j)) <= 1
                      0 <= x(i) <= 1

There is a unique equilibrium solution x(i) = 1/(N+1). Then

   The value for each player: 1/(N+1)^2
   The total value          : N/(N+1)^2 \approx 1/N

The equilibrium is obtained when all agents are playing their optimal selfish
strategy. However, if agents cooperate in a way that the total flow
sum(i, x(i)) is 1/2, then the total value is 1/4, which could be much larger
than 1/N for large enough N. This is called the tragedy of the commons.

Contributor: Youngdae Kim, Dec 2016

$offtext

$if not set TESTTOL $set TESTTOL 1e-4
scalar tol / %TESTTOL% /;
file opt   / 'selkie.opt' /;
file info  / '%emp.info%' /;

set i / 1*5 /;
alias(i,j);

variables obj(i);
positive variables x(i);

equations defobj(i), cap;

defobj(i)..
    obj(i) =E= x(i)*(1 - sum(j, x(j)));

cap..
    sum(i, x(i)) =L= 1;

model m / defobj, cap /;

put info 'equilibrium';
loop(i,
    put / 'max', obj(i), x(i), defobj(i), cap
);
putclose;

x.up(i) = 1;
option emp = selkie;

solve m using emp;
abort$[ smax{i, abs(x.l(i) - 0.1667)} > tol ]  'bad x.l', x.l;
abort$[ abs(cap.m)                    > tol ]  'bad cap.m', cap.m;

$onecho > agent1_gms

Variables  x1,x6,x7,x8,x9,x10;

Positive Variables  x6,x7,x8,x9,x10;

Equations  e1,e6;

e1.. -x6*(1 - x6 - x7 - x8 - x9 - x10) + x1 =E= 0;

e6..    x6 + x7 + x8 + x9 + x10 =L= 1;

* set non-default bounds
x6.up = 1;


* fix levels belonging to other agents
x7.fx = 0;
x8.fx = 0;
x9.fx = 0;
x10.fx = 0;

Model m / e1,e6 /;

Solve m using nlp maximizing x1;

$offecho

execute 'cat agent1_gms > agent1.gms.want';
execute 'cat "%gams.scrdir%agent1.gms" > agent1.gms.got';
execute '=diff -bw agent1.gms.want agent1.gms.got';
abort$errorlevel 'Files agent1.gms.want and agent1.gms.got differ';

$onecho > agent2_gms

Variables  x2,x6,x7,x8,x9,x10;

Positive Variables  x6,x7,x8,x9,x10;

Equations  e2,e6;

e2.. -x7*(1 - x6 - x7 - x8 - x9 - x10) + x2 =E= 0;

e6..    x6 + x7 + x8 + x9 + x10 =L= 1;

* set non-default bounds
x7.up = 1;


* fix levels belonging to other agents
x6.fx = 0;
x8.fx = 0;
x9.fx = 0;
x10.fx = 0;

Model m / e2,e6 /;

Solve m using nlp maximizing x2;

$offecho

execute 'cat agent2_gms > agent2.gms.want';
execute 'cat "%gams.scrdir%agent2.gms" > agent2.gms.got';
execute '=diff -bw agent2.gms.want agent2.gms.got';
abort$errorlevel 'Files agent2.gms.want and agent2.gms.got differ';

$onecho > agent3_gms

Variables  x3,x6,x7,x8,x9,x10;

Positive Variables  x6,x7,x8,x9,x10;

Equations  e3,e6;

e3.. -x8*(1 - x6 - x7 - x8 - x9 - x10) + x3 =E= 0;

e6..    x6 + x7 + x8 + x9 + x10 =L= 1;

* set non-default bounds
x8.up = 1;


* fix levels belonging to other agents
x6.fx = 0;
x7.fx = 0;
x9.fx = 0;
x10.fx = 0;

Model m / e3,e6 /;

Solve m using nlp maximizing x3;

$offecho

execute 'cat agent3_gms > agent3.gms.want';
execute 'cat "%gams.scrdir%agent3.gms" > agent3.gms.got';
execute '=diff -bw agent3.gms.want agent3.gms.got';
abort$errorlevel 'Files agent3.gms.want and agent3.gms.got differ';

$onecho > agent4_gms

Variables  x4,x6,x7,x8,x9,x10;

Positive Variables  x6,x7,x8,x9,x10;

Equations  e4,e6;

e4.. -x9*(1 - x6 - x7 - x8 - x9 - x10) + x4 =E= 0;

e6..    x6 + x7 + x8 + x9 + x10 =L= 1;

* set non-default bounds
x9.up = 1;


* fix levels belonging to other agents
x6.fx = 0;
x7.fx = 0;
x8.fx = 0;
x10.fx = 0;

Model m / e4,e6 /;

Solve m using nlp maximizing x4;

$offecho

execute 'cat agent4_gms > agent4.gms.want';
execute 'cat "%gams.scrdir%agent4.gms" > agent4.gms.got';
execute '=diff -bw agent4.gms.want agent4.gms.got';
abort$errorlevel 'Files agent4.gms.want and agent4.gms.got differ';

$onecho > agent5_gms

Variables  x5,x6,x7,x8,x9,x10;

Positive Variables  x6,x7,x8,x9,x10;

Equations  e5,e6;

e5.. -x10*(1 - x6 - x7 - x8 - x9 - x10) + x5 =E= 0;

e6..    x6 + x7 + x8 + x9 + x10 =L= 1;

* set non-default bounds
x10.up = 1;


* fix levels belonging to other agents
x6.fx = 0;
x7.fx = 0;
x8.fx = 0;
x9.fx = 0;

Model m / e5,e6 /;

Solve m using nlp maximizing x5;

$offecho

execute 'cat agent5_gms > agent5.gms.want';
execute 'cat "%gams.scrdir%agent5.gms" > agent5.gms.got';
execute '=diff -bw agent5.gms.want agent5.gms.got';
abort$errorlevel 'Files agent5.gms.want and agent5.gms.got differ';

* Test the model without writing agent's problem into a file.
putclose opt 'write_agent_model   no';
m.optfile = 1;

obj.l(i) = 0;
x.l(i) = 0;
cap.m = 0;

solve m using emp;
abort$[ smax{i, abs(x.l(i) - 0.1667)} > tol ]  'bad x.l', x.l;
abort$[ abs(cap.m)                    > tol ]  'bad cap.m', cap.m;