
/*
Collective decision or When minority wins
Maurice.Clerc@WriteMe.com
2005-02-18
Last update 2005-03-27 
There are S agents. At the beginning, very few of them do have an opinion.
At each time step, each agent who has an opinion says it to a few
number of others, at random.
Each agent who receives an opinion adopts it, with a probability pr
Even for pr<0.5, after a while, everybody has the same opinion ...
*/


/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "math.h"

//Subroutines
double	alea(double a,double b);
int	alea_integer(int a,int b);

void main()
{
	int k;
	int	K;	// number max of informed agents (by a given one)
	int o;
	int O;	// number of different opinions
	int	Opin[100];	// Opinions of the agents
	int	Opin_number[10]; // For each opinion, number of agents 
	double pr; // Probability to adopt a decision
	int	S;	// number of agents
	int	s,s1,s2;
	int t;
	int T;	// Number of time steps
	
	K=3; 
	S=50;
	O=5;
	pr=0.4;
	T=70;

	// Initialisation
	for (s=0;s<O;s++) Opin[s]=s+1;
	for (s=O;s<S;s++) Opin[s]=0; // No opinion

	for (t=0;t<T;t++)
	{
		// Spreading
		s1=alea_integer(0,S-1);
		for (s=0;s<S;s++)
		{
//	printf("\n s1 %i, opin %i",s1,Opin[s1]);		
			o=Opin[s1]; if (o==0) goto next_s1;

			for (k=0;k<K;k++) // Random information links
			{
				s2=alea_integer(0,S-1);
				if(alea(0,1)<pr)
					Opin[s2]=Opin[s1]; // Adopt the opinion
//printf("\n %i => %i",s1,s2);
			}
next_s1:
			s1=s1+1; if (s1>=S) s1=S-s1;

		}

		// Display opinions
/*	
		for (s=0;s<S;s++)
		{
			printf("\n%i => %i",s,Opin[s]);
		}
*/	
		for (o=0;o<=O;o++) Opin_number[o]=0;
		for(s=0;s<S;s++)
		{
			Opin_number[Opin[s]]=Opin_number[Opin[s]]+1;
		}

		printf("\n");
		for (o=0;o<=O;o++)
		{
			printf("%i ",Opin_number[o]);
		}
	} // Next t

}


//===========================================================
double	alea(double a,double b)
{	// rand number (uniform distribution) in [a b]

double 	r;
 r=(double)rand(); r=r/RAND_MAX;
return a+r*(b-a);
}
//===========================================================
int	alea_integer(int a,int b)
{// Integer rand number in [a b]
int	ir;
double 	r;
r=alea(0,1); ir=(int)(a+r*(b+1-a)); if (ir>b) ir=b;
return ir;
}