Tutorial
Kami’s interface is heavily influenced by Mesa’s interface. However, by being written in C++, Kami runs substantially faster. This allows for faster runs and more runs within a fixed amount of time. The advantage here is that an agent-based model (ABM) built on the Kami platform is better suited for statistical and Monte Carlo approaches to modelling.
Model Form
Kami-based models have five key components:
Agents, which are objects representing the actors within the model
Populations, which are collections of Agents
Domains, which provide a representation of “physical” space the Agent inhabits
Schedulers, which provide a representation of “time” within the model
Model, which are objects connecting Populations, Domains, and Schedulers
In general, a model should have one scheduler, one domain, and some number of agents. However, it would not be impossible to have more than one scheduler or more than one domain. Because this is implemented in C++, your agents should subclass Agent and your model should subclass model. The schedulers and domains are sufficient as is for their purposes though custom schedulers and domains are not unreasonable.
A Minimal ABM
The minimal ABM starts with the simplest possible agent. Here, we
create a class called MinimalAgent
:
1 class MinimalAgent : public kami::Agent {
2 public:
3 kami::AgentID step(std::shared_ptr<kami::Model> model) override {
4 return this->get_agent_id();
5 }
6 };
An Agent
, and its subclasses, will automatically inherit an AgentID
,
which is the unique identifier for the session. The only explicit
requirement on the Agent
subclass is a step() method that accepts
a shared_ptr
to a Model
and it must return the Agent
’s AgentID
.
Obviously, an Agent
should do something useful before returning.
The second component is MinimalModel:
1class MinimalModel: public kami::Model {
2public:
3 MinimalModel() {
4 auto sched = std::make_shared<kami::SequentialScheduler>();
5 set_scheduler(sched);
6
7 auto pop = std::make_shared<kami::Population>();
8 set_population(pop);
9
10 for (auto i = 0; i < 10; i++) {
11 auto new_agent = std::make_shared<MinimalAgent>();
12 pop->add_agent(new_agent);
13 }
14 }
15};
The MinimalModel
performs some important tasks that important to do
during the setup or soon thereafter. In the constructor, first, a
scheduler is created. The SequentialScheduler
is the simplest
scheduler and has no configuration needed. Using set_scheduler(),
part of the Model class, the scheduler is associated with this
model. Second, a Population is created and associated with this
model with the set_population() method.
After this, the constructor initializes 10 MinimalAgents
and adds
them to the population.
1int main() {
2 auto model = std::make_shared<MinimalModel>();
3
4 for (int i = 0; i < 10; i++)
5 model->step();
6
7 return 0;
8}
The last part is our main() function. It creates the MinimalModel
then executes its step() method 10 times. The step() method, by
default, calls the step() method of the scheduler. In the case of
the SequentialScheduler
, it loops over all the Agent
instances in the
Population
and executes the associated step() method of each Agent
.
That is it. It is the simplest minimal model that can be created using the Kami platform. However, for a basis, it is likely better to use the starter model, included in the examples directory.