# グラフを出力する
さて、ここまではマップ出力を使いエージェントの様子を見てきました。グラフ出力機能を使えば、狼や羊の増減をもっとわかりやすく観察することができます。
ここでは時系列グラフを使って牧草、狼、羊の数を出力する方法を学んでいきましょう。
## Universe変数の追加とルールの記述
まず、グラフに出力できるのはUniverse変数です。Universe変数とはモデルツリーのUnverse直下にある変数のことです。早速追加してみましょう。
Universeの右横の「+」を選択して「変数を追加」をクリックします。変数名はnum_grassとしましょう。同じ要領でUniverse変数num_wolfとnum_sheepも作成してください。
次に牧草、狼、羊の数の集計をUniverseのルールで行っていきます。
エージェントの数を数えるのに便利な関数が**count_agt**関数です。
count_agt関数は引数にエージェント種別を指定することでそのエージェント種別のエージェント数を返してくれます。
```
count_agt(agttype=[エージェント種別])
```
```agttype=```と付けることを忘れないようにしましょう。また、今回は使いませんがcount_agt()と引数を書かずに実行するとエージェント種別に関わらずすべてのエージェントの数を数えます。
数の集計はステップごとに行うので、univ_step_beginで毎回ステップの初めに初期化するようにしましょう。
```
def univ_step_begin(self):
# def univ_step_begin(self):に続けてルールを書く
Universe.num_grass = 0
Universe.num_wolf = 0
Universe.num_sheep = 0
create_agt(Universe. ...
```
数の集計は各ステップの最後に行うのが自然ですので、ルールはuniv_step_end内に書いていきます。
univ_step_endに下記のルールを書きましょう。passを消すのも忘れないようにしましょう。
```
def univ_step_end(self):
for x in range(51):
for y in range(51):
# grassが1より大きい場合は牧草の合計数に1足す
if Universe.plain.grass[x, y, 0] >= 1:
Universe.num_grass += 1
Universe.num_wolf = count_agt(agttype=Universe.plain.wolf)
Universe.num_sheep = count_agt(agttype=Universe.plain.sheep)
```
## グラフの出力設定
最後にグラフの出力設定です。マップを追加したときと同じように出力設定画面を開き、「マップ出力」と書かれた部分をクリックし、表示される選択肢から今回は**時系列グラフ**を選びます。今回はステップごとに変化する数を出力したいので時系列グラフが適しています。
```eval_rst
.. image:: images/tutorial2_3/tutorial2-3-1.png
:align: center
:scale: 60%
```
時系列グラフを選んだら「追加」ボタンを押します。グラフ名は「生態系」としておきましょう。X軸ラベルには「ステップ数」、Y軸ラベルには「数」と入れておきます。次に、時系列グラフ要素リストと書かれたエリアの「+」をクリックしましょう。
時系列要素設定画面が表示されると思います。要素名は「牧草の数」、出力値には出力したい変数等を入れます。今回は牧草の数なので「Universe.num_grass / 100」を入力します。100で割っているのは狼と羊の数に比べて牧草の数が多いため一つのグラフに表示したときに見やすくするためです。他の欄はこのままで「OK」を押してください。
```eval_rst
.. image:: images/tutorial2_3/tutorial2-3-2.png
:align: center
:scale: 60%
```
同じようにして狼の数と羊の数についても要素設定をしていきます。今度は出力値で割り算をする必要はないので、該当する変数を減らべばOKです。また、見やすさのために線の色を変えましょう。見本では狼が赤色、羊が青色の線にしておきます。
```eval_rst
.. image:: images/tutorial2_3/tutorial2-3-3.png
:align: center
:scale: 60%
```
実行ボタンを押すとグラフが表示され、数の変化がより分かりやすくなりました。
```eval_rst
.. image:: images/tutorial2_3/tutorial2-3-4.png
:align: center
```
## 発展問題
これでチュートリアル「様々なエージェントの動かし方と出力方法を学ぶ」は終了です。
ここでは狼と羊モデルを少し簡単にして作成しました。
このモデルは様々に改造することが可能です。例えば羊の代謝率や牧草の成長率を導入したり、最初に牧場にいる狼と羊の数をコントロールパネルで操作したり、といった具合です。モデルの改造例を次の発展問題に示します。
ぜひ発展問題に取り組み、狼と羊モデルをパワーアップさせてモデルを公開してみてください。
1. 狼は累計30ステップ分、羊は累計10ステップ分食事ができないと死ぬようにする
- ヒント:狼と羊にそれぞれ空腹度合いを表す変数hungerを追加しましょう。初期値は0にし、食べ物を食べられないときは1ずつ足していきます。hungerが30(あるいは10)になったらエージェントは死亡します。
2. 狼と羊に代謝率を導入し、以下の条件を満たす
- 代謝率はコントロールパネルで操作できるようにする
- 体力の初期値は代謝率の2倍を上限にランダムにセットする
- 食べ物を食べたとき、(代謝率*体力)分体力が増える
- 狼の体力の上限は代謝率の3倍まで、羊の体力の上限は代謝率の2倍までとする
- ヒント:代謝率を表す変数
metabolismを追加しましょう。コントロールパネルで操作するためにはUniverse直下に追加する必要があります。体力はpowerという名前で追加済みの変数を使います。
コントロールパネルの設定は[2.12. コントロールパネルで変数の値を設定する](https://artisoc-cloud.kke.co.jp/documents/tutorial/tutorial1/tutorial1-2.html#id12)を参考に、10%~100%の間で操作できるようにしましょう。
体力の上限については、一度体力を増やした後に「体力が代謝率の3倍(2倍)以上だったら、体力に代謝率の3倍(2倍)を代入する」というルールを書くことでうまくいきます。
3. 牧草の成長ルールについて以下の条件を満たす
- 牧草の成長度上限をコントロールパネルで操作できるようにする
- 牧草の成長度ははじめ、成長度上限を超えない範囲でランダムに割り当てられる
- 羊は成長度上限に達した牧草しか食べられない
- 生態系グラフには成長上限に達した牧草の量を表示する
- ヒント:成長度上限を表す変数limit_grassをUniverse直下に追加しましょう。Universeのルールとsheepのルールを書き換える必要があります。成長度の上限については第2問目の体力の上限と同様に考えます。
空間変数の色が正しく表示されるように気を付けてください。方法の一つとして、空間変数の色を設定するための空間変数grass_colorをplain直下に追加し、(成長度/成長度上限*50)をgrass_colorに代入することでgrass_colorの範囲を0~50に収めることができます。
4. 代謝率、牧草の成長度上限に加え、狼の最初の数、羊の最初の数、狼の繁殖率、羊の繁殖率をコントロールパネルで設定できるようにする
- ヒント:それぞれ、Universe直下に変数をつくりましょう。チュートリアルで作成したモデルでは狼と羊の最初のエージェント数はUniverseでそれぞれ10匹、50匹と設定していました。繁殖率はwolf、sheepのルール内で5%と置いていました。これらの部分を書き換えましょう。
5. コントロールパネルでパラメータを調整して、「ロトカ・ヴォルテラのモデルらしい」個体数の増減を観察する
- ヒント:コントロールパネルでパラメータの数を様々に変えてモデルを実行してみましょう。捕食者と被食者の数が増減を繰り返す様子が見られる組み合わせがあるはずです。
モデル構築により個々のエージェントの振る舞いを定義し、様々なパラメータを与えて全体の現象を観察することはマルチエージェント・シミュレーションの醍醐味です。
チュートリアルの内容に沿って作成した[サンプルモデル](https://artisoc-cloud.kke.co.jp/models/Z7NiafsjScSguBSLmI474A)があります。内容の理解や発展問題のヒントとして役立ててください。