Writing the model’s source files – Implementing the equations and rules for the model
SegregationAgent.cpp
[ACTION] The SegregationAgent file we provide the line that implements the agent’s move behaviour. Add the following lines after //TODO in the SegregationAgent.cpp
//TODO: move to a random empty position
mSpace->moveTo(mId,agentNewLoc);
SchellingTheory.cpp
Situational mechanism
[ACTION] Here we complete the logic of the situational mechanism: the theory looks up the neighbouring agents and calculates the overall similarity percentage. If the percentage is over the threshold, the agent is not satisfied.
//TODO: increase the count if 2 agents are the same type
if ((*agentIter)->getType() == ((SegregationAgent*)mpAgent)->getType()) {
similarCount++;
}
//TODO: if similarity >= threshold, update satisfaction
double similarityPercentage = (double)similarCount/neighbourAgents.size();
double threshold = ((SegregationAgent*)mpAgent)->getThreshold();
mIsSatisfied = (similarityPercentage >= threshold);
Action mechanism
[ACTION] Complete the action mechanism: if the agent is not satisfied, it will have an intention to move.
//TODO: if not satisfied, moving intention =TRUE else =FALSE
mMovingIntention = ! mIsSatisfied;
SegregationTheoriesMediator.cpp
Mediate situational mechanisms
[ACTION] The mediator will trigger situational mechanisms in all theories. Since there is only one theory in this tutorial, it does not have to mediate anything and just passes the satisfaction value from a SchellingTheory object to a SegregationAgent object.
//TODO: trigger situation mechanisms
((SchellingTheory*) mTheoryList[0])->doSituation();
//TODO: get the satisfaction value from the Theory object
bool updatedSatisfation = ((SchellingTheory*) mTheoryList[0])->getSatisfiedStatus();
//TODO: because there is only one theory, pass satisfaction value to the agent
((SegregationAgent*) mpAgent)->setSatisfiedStatus(updatedSatisfation);
Mediate action mechanisms
[ACTION] In the action mechanism, even though the mediator does not have to mediate anything, it makes a final decision for whether the agent will move based on its intention.
//TODO: trigger action mechanisms
mTheoryList[0]->doAction();
//TODO: if the agent intends to move, perform the move action
if (((SchellingTheory*) mTheoryList[0])->getMovingIntention())
((SegregationAgent*) mpAgent)->move();
Board.cpp
[ACTION] In the transformational mechanism, the board will update the average satisfaction and segregation index.
//TODO: transformational mechanisms: update avg satisfaction and segregation index
updateAvgSatisfaction();
updateSegregationIndex();
SegregationModel.cpp
Initialization
[ACTION] Create and initialize the entities in the model: the Board and SegregationAgent objects.
//TODO: init at the macro level: the Board structural entity
mpBoard = new Board(&mContext, discreteSpace);
//TODO: init at the micro level: agent, theory, theory mediator
//create Agent object
SegregationAgent* agent = new SegregationAgent(id, type, threshold, discreteSpace);
//create Theory object
SchellingTheory* theory = new SchellingTheory(&mContext, discreteSpace);
//create Mediator object
std::vector<Theory*> theoryList;
theoryList.push_back(theory);
TheoryMediator* mediator = new SegregationTheoriesMediator(theoryList);
//connect the Agent with the Mediator
agent->setMediator(mediator);
mediator->setAgent(agent);
//add the Agent to context and discrete space
mContext.addAgent(agent);
discreteSpace->moveTo(id, initialLocation);
Mechanisms
[ACTION] Here we write the code to trigger the situational and action mechanisms from SegregationAgent objects and trigger transformational mechanisms from the Board. Call the three mechanisms in the correct order for the Schelling model: first the situational mechanisms, then the action mechanisms, then the transformational mechanisms.
//TODO: call doSituation for each agent
(*iter)->doSituation();
//TODO: call doAction for each agent
(*iter)->doAction();
//TODO: call doTransformation of the Board structural entity
mpBoard->doTransformation();
//TODO: call three mechanisms in the correct order
doSituationalMechanisms();
doActionMechanisms();
doTransformationalMechanisms();
Scheduler
[ACTION] Schedule the defined sequence of mechanisms every discrete time step (these are called ‘ticks’ in Repast) and also the time at which to stop the simulation (this is read in from a model properties file: model.props)
//TODO: schedule actions every tick
runner.scheduleEvent(2, 1, repast::Schedule::FunctorPtr(new
repast::MethodFunctor<SegregationModel> (this, &SegregationModel::doPerTick)));
//TODO: schedule stopping condition at max tick
runner.scheduleStop(mStopAt);