/* C Program to Sequentially Search for Voter Nash Equilibria by Jeffrey S. Rosenthal, http://probability.ca/jeff/ This program investigates an algorithm of repeated candidate action tweaks in an attempt to converge to equilibrium behaviour, in Model 4* of voting behaviour as discussed and analysed in the paper "Many-Candidate Nash Equilibria for Elections Involving Random Selection", available at: http://probability.ca/jeff/ftpdir/runoff.pdf This file is "runoff.c". Adjust the parameters n, alpha, NUMREPS, AV below as desired. Then e.g. compile with "cc runoff.c", and run as "a.out". The resulting output is designed to be read into the free statistical software R, to produce graphical barplots. */ #include #include #include #define NUMREPS 1000 #define BURNIN (NUMREPS/2) #define NUMAV 100 int n=5; double alpha=2.9; int verbose=0; int maxmark = 10; double inc, drand48(); /* v=Unif[0,1] */ /* Notation: position x[i] = mark[i] / maxmark = mark[i] * inc */ /* Also, locmark[i] = -999 if OUT, or -r if eliminated on r'th round. */ int main() { double *avrpayoffvec(), curpayoff[99], newpayoff[99], *tmppayoff; int curmark[99], newmark[99], randmark(); void seedrand(); int i, rep, mover; int outcount=0, numcounted=0, markcount[99]; int numc = imin(n, ifloor(alpha)+1); seedrand(); inc = 1.0/maxmark; /* Zero the counts. */ outcount=0; numcounted=0; for (i=0; i<=maxmark; i++) markcount[i] = 0; /* Random action initialisation. */ for (i=0; i= 2) { printf("initial mark values: "); for (i=0; i= 2) printf("mover is %d\n", mover); for (i=0; i= 2) { printf("new mark values: "); for (i=0; i curpayoff[mover]) { if (verbose >= 1) printf("Candidate %d from %d to %d increasing from %.3f to %.3f.\n", mover, curmark[mover], newmark[mover], curpayoff[mover], newpayoff[mover]); curmark[mover] = newmark[mover]; for (i=0; i BURNIN) { numcounted++; for (i=0; i= 1) { printf("mark values %d: ", rep+1); for (i=0; i= 2) { printf("final mark values: "); for (i=0; i= 2) { stepnum++; /* Reset the counters. */ minv = 2.0; maxv = -1.0; winner = -1; numlosers = 0; for (j=0; j<=maxmark; j++) markmult[j] = 0; totcontest = 0; /* Compute positions x[i], and markmult multiplicities. */ for (i=0; i= 0) { markmult[locmark[i]]++; totcontest++; } } for (i=0; i= 0) { /* Compute vote share of player i. */ v[i] = ( rightend(x,i) - leftend(x,i) ) / markmult[locmark[i]]; /* Check for winners and losers. */ if (v[i] >= maxv) { maxv = v[i]; winner = i; } if (v[i] == minv) { loser[numlosers] = i; numlosers++; } else if (v[i] < minv) { minv = v[i]; loser[0] = i; numlosers=1; } if (verbose >= 3) printf("i=%d, left=%f, right=%f, v=%f, winner=%d\n", i,leftend(x,i),rightend(x,i),v[i],winner); } } if (verbose >= 2) { printf("current local mark values: "); for (i=0; i= 2) { printf(" loser list: "); for (j=0; j= 2) && (numlosers >= 1) ) { theloser = randint(0,numlosers-1); if (verbose >= 2) printf("The chosen loser is: loser[%d]=%d\n", theloser, loser[theloser]); locmark[ loser[theloser] ] = -stepnum; } } if (verbose >= 2) printf("winner = %d\n", winner); if (verbose >= 2) { for (i=0; i= 2) { for (i=0; isofar) sofar = newbound; } } return sofar; } double rightend(double xx[3], int ii) { int jj; double newbound; double sofar = +1; for (jj=0; jjxx[ii]) ) { newbound = (xx[jj]+xx[ii])/2; if (newbound