先日旧質問掲示板で質問した「相続制度の実現に当たって子供リストを取得したかった。」の問題が解決していないので再質問します。
モデルの趣旨としてはある2地点を往復しながら出産するエージェントのモデルで、この親子関係を正確に保持させようとしたところ期待しない挙動をしたのが今回解決したい問題です。
以下のモデルを構築し、人エージェントから親エージェント集合に対して線を引いたものの挙動が不自然で、
子エージェント集合に対して行った同様の処理と比較して異なる挙動をする。
遠すぎるエージェントに線が引かれることがある。
あるエージェントに対して“自称親”が複数登場する。
等の挙動をする。
これの原因が知りたいです。
元のモデルの本問題とは関係ない部分を可能な限り取り去った上で問題の再現性があるように再構築したものがこちらです。変数の初期状態は変更していませんが、「地域」はループしない設定に変更しています(両端の矢印の可視性が低い為)。
ルール:Universe
Univ_Init{
mergeagtset(universe.空き地,createagtmulti(universe.地域.土地, getheightspace(universe.地域) * getwidthspace(universe.地域)) )//土地 生成
randomputagtsetcell(universe.空き地, False)//配置
createagtmulti(universe.地域.人, 5)//人 生成
}
Univ_Step_Begin{}
Univ_Step_End{}
Univ_Finish{}
ルール:人
Agt_Init{
if getcountstep() == 0 then
my.X = rnd()*50; my.Y = rnd()*50
else
同じ位置にする(my, universe.直前出産者)
addagt(my.親, universe.直前出産者)//問題の箇所
end if
dim 近くの空き地 as agtset
MakeAgtSetAroundPositionCell(近くの空き地, universe.地域, my.X, my.Y, 0, 5, universe.空き地)
if countagtset(近くの空き地) > 1 then
//農地
my.仕事場 = pickupagt(近くの空き地, rnd() * CountAgtset(近くの空き地))
delagtset2(universe.空き地,my.仕事場)
//家
my.家 = pickupagt(近くの空き地, rnd() * CountAgtset(近くの空き地))
delagtset2(universe.空き地,my.家)
//その他変数
my.目的地 = my.仕事場
else killagt(my)
end if
}
Agt_Step{
//移動
pursue(my.目的地, 1)
if 同じ位置か(my, my.仕事場) then
my.目的地 = my.家
elseif 同じ位置か(my, my.家) then
my.目的地 = my.仕事場
end if
//出産
universe.直前出産者 = my
addagt(my.子, createagt(universe.地域.人)) //問題の箇所
}
sub 同じ位置にする(移動主体 as agt, 移動先 as agt){移動主体.X = 移動先.X ;移動主体.Y = 移動先.Y}
function 同じ位置か(A as agt, B as agt) as boolean{return(A.X == B.X and A.Y == B.Y)}
ルール:土地
Agt_Init{}
Agt_Step{}
変数の構成
親に引いた線と子に引いた線の比較
自己解決しました。
子エージェント集合に追加する前に if not specifykillagt(one) といった風に条件付けして死産したエージェントを追加しないようにすればよいようです
死産つまりinit()内での死は親が死亡フラグを読むという処理が入る都合上killagt()以外の処理ではエラーが発生します。
死産以外の死、つまりAgt_step()内での死はkillagt()やdelagt()では親の変数が初期化されない為か同様のバグが発生してしまいます。