// Paul Johnson August 2, 2000 //pjrepeater6.m. Decentralized scheduling as in pjrepeater4.m runs //a bit too slowly, so searching for a speedup, I have used a different //scheduling strategy. Suppose a "day" is 10 steps, and on the first //step of each day, each agent is told to "step", which means to //schedule its actions for the rest of that day. Create 1 "master //schedule" that agents all use. If all actions arriving in the //schedule at each time must be randomized, then the concurrent group //option can be used to mix that up. That slows things down a bit. //If you don't do that, there is still a high degree of randomization //because the agents are told to step in a randomized order at the //beginning of each day. // Paul Johnson July 13, 2000 // pjrepeater5.m. In the interest of personal enlightenment and // education, consider introducing a single "masterSchedule" that all // agents can put their actions on. The customization of the schedule // object occurs in the bugSwarm level. Note we have a usave of // "ConcurrentGroup" rather than the customization steps used in the // previous example. // We (Marcus Daniels and I) are not recommending the approach here, // just illustrating it. pjrepeater4.m showed the best way to design // these decentralized schedules of swarms in swarms. //Marcus said, and I agree, "Here's how to configure the shared //masterSchedule. In some cases it may be easier to look at the //emergent structure of dynamic schedules if there is a shared, //e.g. xfprint (masterSchedule). //But, generally, I think it is better to have schedules in the agents //themselves. That way it is more "agent-based" and modular. // decentralized scheduling using customized schedule type to // randomize events that arrive on the scheduling mechanism for the // same time. #import #import #import #import @interface Bug: Swarm { int idnum; id schedule; } - scheduleSelfAt: (timeval_t)x; - setSchedule: sch; - setID: (int)x; - print; @end @implementation Bug - scheduleSelfAt: (timeval_t)x { [schedule at: x createActionTo: self message: M(print)]; return self; } - setSchedule: sch { schedule= sch; return self; } - setID: (int) x { idnum=x; return self; } - print { fprintf (stderr,"I'm %s, Number %d and the current time is %ld\n", [self getName], idnum, getCurrentTime ()); return self; } @end @interface BugA: Bug - step; @end @implementation BugA - step { #ifdef MARCUS { timeval_t rand= getCurrentTime()+2; fprintf(stderr,"BugA Num %d: there should be action at %ld \n", idnum, rand ); [self scheduleSelfAt: rand ]; //here is a phony action that makes the randomized model swarm "stepSchedule" work: [schedule at: getCurrentTime()+10 createActionTo: self message: M(isClass)]; } #else { timeval_t rand= [uniformIntRand getIntegerWithMin: 0 withMax:10]; fprintf(stderr,"BugA Num %d: rand=%ld, there should be action at %ld \n", idnum, rand, getCurrentTime() +rand ); [self scheduleSelfAt: getCurrentTime()+rand ]; //here is the phony action that makes the schedule work: [schedule at: getCurrentTime()+10 createActionTo: self message: M(isClass)]; } #endif return self; } @interface BugB: Bug - step; @end @implementation BugB - step { #ifdef MARCUS { timeval_t rand= 5+getCurrentTime(); fprintf(stderr,"BugB Num %d: there should be action at %ld \n", idnum, rand); [self scheduleSelfAt: rand ]; } #else { timeval_t rand= [uniformIntRand getIntegerWithMin: 0 withMax: 9]; fprintf(stderr,"BugB Num %d: rand=%ld,there should be action at %ld \n", idnum, rand, getCurrentTime() +rand ); [self scheduleSelfAt: getCurrentTime()+rand ]; } #endif return self; } @interface BugSwarm: Swarm { id masterSchedule; id bugList; } - buildObjects; - setTheList: list; - buildActions; - (id )activateIn: (id )swarmContext; @end @implementation BugSwarm - buildObjects { [super buildObjects]; { id groupProto; groupProto = [ConcurrentGroup customizeBegin: self]; [groupProto setDefaultOrder: Randomized]; groupProto = [groupProto customizeEnd]; masterSchedule = [Schedule createBegin: self]; // [masterSchedule setConcurrentGroupType: groupProto]; [masterSchedule setAutoDrop: YES]; masterSchedule = [masterSchedule createEnd]; } [bugList forEach: M(setSchedule:): masterSchedule]; return self; } - setTheList: list { bugList = list; return self; } - buildActions { [super buildActions]; return self; } - (id )activateIn: (id )swarmContext { [super activateIn: swarmContext]; [masterSchedule activateIn: self]; return [self getActivity]; } @end @interface ModelSwarm: Swarm { id schedule; id stepSchedule; id bugSwarm; id bugList; } - announcement; - buildObjects; - buildActions; - activateIn: swarmContext; @end @implementation ModelSwarm - announcement { fprintf (stderr,"I'm model swarm, current time is %ld\n", getCurrentTime()); return self; } - buildObjects { [super buildObjects]; bugList = [ List create: self]; [bugList addLast: [[BugA create: self] setID: 0]]; [bugList addLast: [[BugA create: self] setID: 1]]; [bugList addLast: [[BugA create: self] setID: 2]]; [bugList addLast: [[BugA create: self] setID: 3]]; [bugList addLast: [[BugA create: self] setID: 4]]; [bugList addLast: [[BugB create: self] setID: 5]]; [bugList addLast: [[BugB create: self] setID: 6]]; [bugList addLast: [[BugA create: self] setID: 7]]; [bugList addLast: [[BugB create: self] setID: 8]]; [bugList addLast: [[BugA create: self] setID: 9]]; [bugList forEach: M(buildObjects)]; bugSwarm = [BugSwarm createBegin: self]; bugSwarm = [ bugSwarm createEnd]; [bugSwarm setTheList: bugList]; [bugSwarm buildObjects]; return self; } - buildActions { id modelActions; [super buildActions]; modelActions = [ActionGroup create: self]; [bugSwarm buildActions]; stepSchedule = [Schedule create: self setRepeatInterval: 10]; // [modelActions createActionForEach: bugList message: M(step)]; [ [modelActions createActionForEach: bugList message: M(step)] setDefaultOrder: Randomized]; [stepSchedule at: 0 createActionTo: self message: M(announcement)]; [stepSchedule at: 0 createAction: modelActions]; return self; } - activateIn: swarmContext { [super activateIn: swarmContext]; [stepSchedule activateIn: self]; [bugSwarm activateIn: self]; return [self getActivity]; } @end @interface ObserverSwarm: GUISwarm { id modelSwarm; id displaySchedule; } - buildObjects; - buildActions; - (id )activateIn: (id )swarmContext; @end @implementation ObserverSwarm - buildObjects { [super buildObjects]; modelSwarm = [ModelSwarm create: self]; [controlPanel setStateStopped]; [modelSwarm buildObjects]; return self; } - buildActions { [super buildActions]; [modelSwarm buildActions]; displaySchedule = [Schedule create: self setRepeatInterval: 1]; [displaySchedule at: 0 createActionTo: actionCache message: M(doTkEvents)]; return self; } - (id )activateIn: (id )swarmContext { [super activateIn: swarmContext]; [modelSwarm activateIn: self]; [displaySchedule activateIn: self]; return [self getActivity]; } int main (int argc, const char **argv) { id swarm; initSwarm (argc, argv); swarm = [ObserverSwarm create: globalZone]; [swarm buildObjects]; [swarm buildActions]; [swarm activateIn: nil]; [swarm go]; return 0; } /* Local Variables: compile-command: "$SWARMHOME/bin/libtool-swarm --mode=link gcc -D_GNU_SOURCE \ -DAPPNAME=pjrepeater6 -o pjrepeater6 -Wall -Werror -g -Wno-import -I$SWARMHOME/include \ -I$SWARMHOME/include/swarm -L$SWARMHOME/lib/swarm pjrepeater6.m -lswarm -lobjc" End: */