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"];
Top Related