Programming for Social Scientists Lecture 5 UCLA Political Science 209-1: Programming for Social...

37
Programming for Social Scientists Lecture 5 UCLA Political Science 209-1: Programming for Social Scientists Winter 1999 Lars-Erik Cederman & Benedikt Stefansson
  • date post

    20-Dec-2015
  • Category

    Documents

  • view

    214
  • download

    0

Transcript of Programming for Social Scientists Lecture 5 UCLA Political Science 209-1: Programming for Social...

Programming for Social Scientists

Lecture 5UCLA Political Science 209-1: Programming for Social

Scientists

Winter 1999

Lars-Erik Cederman & Benedikt Stefansson

POL SCI 209-1 Cederman / Stenfansson

2

Today's topics

• lists of agents

• random number generators

• loading parameters from file

• nested Swarms

Example 1: SimpleList

Example 2: Evol IPD

(evolutionary version of SimpleIPD)

POL SCI 209-1 Cederman / Stenfansson

3

Managing many agents

• Swarm offers the class Collection

• Collections can be of type:– List (today's focus!)– Array (different from arrays in C!)– Keyed Collection (maps and sets)

Note: Collections are dynamic data structures that can change during run-time (cf. pointers in C)

POL SCI 209-1 Cederman / Stenfansson

4

Arrays and Linked Lists

3 18 2 5 7 4 9 27

Array: fast access

3 8 2 5

Linked list: flexibility

POL SCI 209-1 Cederman / Stenfansson

5

Lists in Swarm

obj1 obj2 obj3 obj4

list = [List create: self][list atOffset: 3]

index = [list begin: self]

obj=[index next]

[list addLast: obj4]

POL SCI 209-1 Cederman / Stenfansson

6

SimpleList

• Create 10 elements in a linked list

• Print them

• Repeat 10 times:– Scramble the order– Print the elements again

POL SCI 209-1 Cederman / Stenfansson

7

SimpleList: Sample Output

Count: 10

List: 0 1 2 3 4 5 6 7 8 9

Repl 1: 8 2 0 1 4 7 9 3 5 6

Repl 2: 9 0 3 6 5 1 8 2 4 7

...

Repl 10: ...

POL SCI 209-1 Cederman / Stenfansson

8

SimpleList: File Structure

main.mModel-

Swarm.m Element.m

Element.hModel-Swarm.h

POL SCI 209-1 Cederman / Stenfansson

9

SimpleList: main.m

#import "ModelSwarm.h"

int main(int argc, const char ** argv) {

id modelSwarm;

initSwarm(argc, argv);

modelSwarm = [ModelSwarm create: globalZone];

[modelSwarm buildObjects: 10];

[modelSwarm run];

return 0;

}

POL SCI 209-1 Cederman / Stenfansson

10

SimpleList: Element.h/m

// Element.h

#import <objectbase.h>

#import <objectbase/SwarmObject.h>

@interface Element: SwarmObject {

int name;

}

-init: (int) n;

-(int) getID;

@end

// Element.m

#import "Element.h"

@implementation Element

-init: (int) n {

name = n;

return self;

}

-(int) getID {

return name;

}

@end

POL SCI 209-1 Cederman / Stenfansson

11

SimpleList: ModelSwarm.h#import "Element.h"

#import <objectbase.h>

#import <objectbase/Swarm.h>

#import <random.h>

@interface ModelSwarm: Swarm {

id objList;

}

+createBegin: (id) aZone;

-createEnd;

-buildObjects: (int) n;

-printObjects: list;

-shuffle: list;

-run;

@end

POL SCI 209-1 Cederman / Stenfansson

12

SimpleList: ModelSwarm.m (1)

#import "ModelSwarm.h"

@implementation ModelSwarm

+createBegin: (id) aZone {

ModelSwarm * obj;

obj = [super createBegin: aZone];

return obj;

}

-createEnd {

return [super createEnd];

}

-buildObjects: (int) n {

int i;

id anElement;

objList = [List create:self];

for (i=0; i<n; i++) {

anElement = [Element create: self];

[anElement init: i];

[objList addLast: anElement];

}

return self;

}

POL SCI 209-1 Cederman / Stenfansson

13

SimpleList: ModelSwarm.m (2)

-printObjects: list {

id index, anElement;

index = [list begin: self];

while ((anElement=[index next]))

printf("%d ", [anElement getID]);

[index drop];

printf("\n");

return self;

}

POL SCI 209-1 Cederman / Stenfansson

14

SimpleList: ModelSwarm.m (3)

-shuffle: list {

int j, k;

id temp;

j = [list getCount];

while (j>1) {

k = [uniformIntRand getIntegerWithMin: 0 withMax: j-1];

j--;

temp = [list atOffset: k];

[list atOffset: k put: [list atOffset: j]];

[list atOffset: j put: temp];

}

return self;

}

POL SCI 209-1 Cederman / Stenfansson

15

SimpleList: ModelSwarm.m (4)

-run {

int randomSeed;

printf("Count: %d\n", [objList getCount]);

printf("List: ");

[self printObjects: objList];

for (randomSeed=1; randomSeed<=10; randomSeed++) {

[randomGenerator setStateFromSeed: randomSeed];

[self shuffle: objList];

printf("Repl %2d: ", randomSeed);

[self printObjects: objList];

}

return self;

}

@end

POL SCI 209-1 Cederman / Stenfansson

16

Some Collection syntax• getCount

– Gives number of members

• atOffset: i– Retrieves member at location i

• atOffset:i put: obj– Inserts obj at location i

• addFirst: o addLast: o– Adds o at start/end of list

• getFirst,getLast– Returns first/last member

• contains: o– Returns 1 if o is member

• remove: o– Removes object o

• removeAll– Removes all

• forEach:M(message)– Sends message to all members

• removeFirst/Last– removes and returns first/last

member

POL SCI 209-1 Cederman / Stenfansson

17

Accessing Collections with Index

• Any collection can generate an index of itself

• The index behaves as an object, and understands messages such as:– prev,next

– findNext: o,findPrev: o

• Using index to loop over all members:

index=[list begin: zone];

while(o=[index next])

value=[o getValue];

[index drop];

POL SCI 209-1 Cederman / Stenfansson

18

Typical use of List

• Typical use of a List instance is to keep track of agent population

• At create time Model initializes each agent and puts him on agentList

• The agentList is then accessed by Schedule, GUI objects and so on...

• Example

for(i=0;i<numAgents;i++) {

a=[Agent create: zone];

[a setVar1: var1];

[a setVar2: var2];...

[a setVarN: varN];

[agentList addLast: a];

}

POL SCI 209-1 Cederman / Stenfansson

19

Generating Random Numbers

• To draw random numbers from a distribution you’ll need– a generator

• random seed - an integer number which primes the generator

– a distribution

Generator

Distribution

a seed

random sequence of numbers

POL SCI 209-1 Cederman / Stenfansson

20

Default distributions

• When calling initSwarm in main, three default distributions are generated, fed by a default generator

• It is also possible to choose other generators and distributions by using the Random library (more about that later...)

MT19937Generator

UniformInteger

UniformUnsigned

Integer

UniformDouble

POL SCI 209-1 Cederman / Stenfansson

21

Using the default distributions• Default distributions are global • Can call any distribution from any agent • For a double in interval [minVal, maxVal]:

[uniformDblRand getDoubleWithMin: minVal withMax: maxVal];

• For an integer in interval [minVal, maxVal]: [uniformIntegerRand getDoubleWithMin: minVal

withMax:maxVal];

• To set the seed to Val:[randomGenerator setStateFromSeed: Val];

POL SCI 209-1 Cederman / Stenfansson

22

Looking up documentationMain resource:

http://www.santafe.edu/projects/swarm/

Reference manual:

e.g. Collections, Random libraries; see also index

See e.g. Collection [p. 94]:

Name Collection

Description ...

Protocols adopted by Collection: Create, ... Copy, Drop...

MethodsPhase: Creating

Phase: Using

-(BOOL)getCount

-(BOOL)contains: aMember

POL SCI 209-1 Cederman / Stenfansson

23

Evol IPD

• To manage more than two players we add a playerList

• Tournament is a nested swarm letting two agents play IPD

main

ModelSwarmpopList

Tournament

newListwinner

POL SCI 209-1 Cederman / Stenfansson

24

Riolo's GA algorithm in pseudo-code (see Sci. Am.)

while (NewPopNotFull) {

i=random()/PopSize;

j=random()/PopSize;

if (URand01() < 0.75)

Copy most fit of Pop[i],Pop[j] to NewPop

else

Copy least fit of Pop[i],Pop[j] to NewPop;

}

Pop = NewPop;

POL SCI 209-1 Cederman / Stenfansson

25

Evol IPD: File Structure

main.mModel-

Swarm.mTourna-ment.m

Tourna-ment.h

Model-Swarm.h

Player.m

Player.h

POL SCI 209-1 Cederman / Stenfansson

26

Evol IPD: main.m#import <simtools.h>

#import "ModelSwarm.h"

int main(int argc, const char ** argv) {

id modelSwarm;

initSwarm(argc, argv);

modelSwarm = [ModelSwarm create: globalZone];

[modelSwarm buildObjects];

[modelSwarm run];

return 0;

}

POL SCI 209-1 Cederman / Stenfansson

27

Evol IPD: ModelSwarm.h#import "Player.h"

#import "Tournament.h"

#import <objectbase.h>

#import <objectbase/SwarmObject.h>

#import <space.h>

#import <activity.h>

#import <random.h>

@interface ModelSwarm: Swarm { id popList,newList; int numGen, randomSeed; int numPlayers, num[4], n0, n1, n2, n3; double selectionPressure;}+createBegin: (id) aZone;-createEnd;-buildObjects;-runTournament;-reportResults: (int)gen;-run;@end

POL SCI 209-1 Cederman / Stenfansson

28

Evol IPD: ModelSwarm.m (1)#import "ModelSwarm.h"

#import <simtools.h>

@implementation ModelSwarm

+createBegin: (id) aZone {

ModelSwarm * obj;

obj = [super createBegin: aZone];

obj->numGen = 10;

return obj;

}

-createEnd {

[ObjectLoader load: self fromFileNamed: "model.setup"];

return [super createEnd];

}

POL SCI 209-1 Cederman / Stenfansson

29

Evol IPD: ModelSwarm (2)

-buildObjects {

id aPlayer;

int pt,i;

[randomGenerator setStateFromSeed: randomSeed];

time = 0;

num[0] = n0;

num[1] = n1;

num[2] = n2;

num[3] = n3;

numPlayers = n0+n1+n2+n3;

popList = [List create: self];

newList = [List create: self];

for (pt = 0; pt < 4; pt++)

for (i = 0; i < num[pt]; i++) {

aPlayer = [Player createBegin: self];

[aPlayer setPlayerType: pt];

aPlayer = [aPlayer createEnd];

[popList addLast: aPlayer];

}

return self;

}

POL SCI 209-1 Cederman / Stenfansson

30

Evol IPD: ModelSwarm.m (3)-runTournament {

id tournament;

id tempList;

id player1, player2, survivor, newPlayer;

int i, p1, p2;

for (i=0; i<numPlayers; i++) {

p1 = [uniformIntRand getIntegerWithMin: 0 withMax: numPlayers-1];

p2 = [uniformIntRand getIntegerWithMin: 0 withMax: numPlayers-1];

player1 = [popList atOffset: p1];

player2 = [popList atOffset: p2];

tournament = [Tournament createBegin: self];

[tournament setPlayer1: player1 Player2: player2];

[tournament createEnd];

[tournament run];

// for loop cont'd

POL SCI 209-1 Cederman / Stenfansson

31

Evol IPD: ModelSwarm.m (4) if ([uniformDblRand getDoubleWithMin: 0.0 withMax: 1.0] <

selectionPressure)

survivor=[tournament getWinner];

else

survivor=[tournament getLoser];

newPlayer=[Player create: self];

[newPlayer initPlayerType: [survivor getPlayerType]];

[newList addLast: newPlayer];

}

[tournament drop];

[popList deleteAll];

// Swapping lists

tempList = popList;

popList = newList;

newList = tempList;

return self;

}

POL SCI 209-1 Cederman / Stenfansson

32

Evol IPD: ModelSwarm.m (5) -reportResults: (int) gen {

id index;

id aPlayer;

int pt;

for (pt=0; pt<4; pt++)

num[pt] = 0;

index = [popList begin: self];

while((aPlayer=[index next]))

num[[aPlayer getPlayerType]]++;

[index drop];

printf("Time: %4d Num: %6d %6d %6d %6d\n", gen, num[0], num[1], num[2], num[3]);

return self;

}

POL SCI 209-1 Cederman / Stenfansson

33

Evol IPD: ModelSwarm.m (6)

-run {

int gen;

[self reportResults: 0];

for (gen = 1; gen <= numGen; gen++) {

[self runTournament];

[self reportResults: gen];

}

return self;

}

@end

POL SCI 209-1 Cederman / Stenfansson

34

Evol IPD: Tournament.h

#import "Player.h"#import <objectbase.h>#import <objectbase/Swarm.h>#import <space.h>#import <activity.h>

@interface Tournament: Swarm { id player1, player2; int numIter;}+createBegin: (id) aZone;-createEnd;-setPlayer1: p1 Player2: p2;-updateMemories;-distrPayoffs;-(id)getWinner;-(id)getLoser;-run;@end

POL SCI 209-1 Cederman / Stenfansson

35

Evol IPD: Tournament.m

...

@implementation Tournament

...

-setPlayer1: p1 Player2: p2 ...

-updateMemories...

-distrPayoffs...

-(id)getWinner {

int winner;

if ([player1 getPayoff] >

[player2 getPayoff])

winner = player1;

else

winner = player2;

return winner;

}

-(id)getLoser...

-run {

int time;

numIter = 4;

[player1 setPayoff: 0];

[player2 setPayoff: 0];

for (time=0; time<numIter; time++) {

[self updateMemories];

[player1 step: time];

[player2 step: time];

[self distrPayoffs];

}

return self;

}

POL SCI 209-1 Cederman / Stenfansson

36

Evol IPD: Player.m

...

int iParam[4] = {1, 1, 0, 0};

int pParam[4] = {1, 1, 0, 0};

int qParam[4] = {1, 0, 1, 0};

@implementation Player

-setPlayerType: (int) pt {

type = pt;

return self;

}

-(int) getPlayerType {

return type;

}

...

-step: (int) time {

if (time==0)

newAction = iParam[type];

else {

if (memory==1)

newAction = pParam[type];

else

newAction = qParam[type];

};

return self;

}

@end

POL SCI 209-1 Cederman / Stenfansson

37

• The model.setup file:@beginrandomSeed 8251777selectionPressure 0.75numGen 15n0 64n1 64n2 64n3 64@end

• ObjectLoader needs– target object– name of file

Loading/Saving state• ObjectLoader

– Reads values of ivars from file

• ObjectSaver – Writes values of ivars

to file

• Any instance vars not mentioned in infile unchanged [ObjectLoader load: self

fromFileNamed:"model.setup"];