S4 Simulation SystemについてのFAQのページです。

機能について

Aシミュレーションを行うには、現実実際の複雑なシステムをコンピュータ上に簡略化してシミュレーションモデルとして実装する必要があります。この作業をモデル化といいます。S4 Simulation System ではこのモデル化を支援するために、GUIやpsim言語を提供しています。
A数理計画法による最適化では、最適化したい事象を数理計画問題と呼ばれる数式に定式化し、それを解く事で最適化を行います。与えられた事前情報が確定的であるような最適化に有効です。 当社ではNuorium Optimizerを用いた最適化が該当します。
シミュレーションによる最適化は、実際の事象をシミュレーションした結果を最適化する為、数式では表現できなかったり、解析的には解けないような最適化を行う事が可能です。与えられた事前情報が確率的な要素を含む場合に有効です。
A統計モデルによる予測は、過去のデータを統計的に分析し予測する手法です。回帰分析などの線形モデルや、Support Vector Machine、Neural networkのような非線形モデルによる予測などがあります。一方、シミュレーションによる予測では、システムの内部構造をモデル化して、その挙動をシミュレートすることで、対象システムの動的特性を解明する事ができます。
A当社が独自に開発したシミュレーション記述言語です。Pythonをベースにシミュレーション記述に便利なAPIを数多く提供しています。psim 言語は、複雑なシミュレーションも柔軟にシミュレーションできるように設計されています。Python の generator 機能を利用している為、非常に軽量に動作します。psim言語の解説はこちらをご覧ください。
A 混雑状況や利用状況の表示や、リアルタイムグラフでのモニタリング、人、モノの移動をアニメーション表示する事が出来ます。背景画像を設定する事で、より直観的な表示も可能です。2D表示、3D表示が可能です


導入に際して

A 毎月シミュレーションの無料体験セミナーを行っています。 シミュレーションとは何かといった基本的な解説から行っておりますので、シミュレーションについて初めての方にも安心してご受講頂けます。 セミナーの詳細については、こちらをご参照ください。
AS4 Simulation System は GUI 上でシミュレーションが出来てしまうため、プログラミングが出来ない方にも安心してご利用頂けるようになっております。
Aシミュレーションモデルの受託開発も行っていますし、お客様のシミュレーションモデル作成支援の為、個別サポートなどのコンサルティングも行っております。
Aスタンドアロン版、C/S版がございます。台数割引、ユーザ数割引もございます。金額はお問合せページよりお問合せください。
A学生の皆さまや、ご研究に広くご利用頂けるようにアカデミックの方向けには、特別価格をご用意しております。金額はお問合せページよりお問合せください。
Aスタンドアロン版には台数割引、C/S版にはユーザ数割引がございます。
Aご予算に応じたご導入プランをご提案いたします。 お問合せページよりお問合せください。
AS4 Simulation System はシミュレーション教育にも適したソフトウェアです。学部生でも問題なく実習授業でご利用頂いております。詳細については早稲田大学様の事例をご覧ください。 また、S4 Simulation Systemでは学生研究の発表の場として、学生研究奨励賞を募集しております。こちらで学生研究事例を紹介しています。


インストールに関して

A S4 Simulation Systemのインストールが失敗する原因は複数考えられます。ごく基本的なものも含め、以下に典型的な原因を列挙いたします。
1. インストールPCのOSが対象OSでない。対象OSはこちらのFAQから「Q. 動作環境を教えてください。」をご確認ください。

2. Windows Update により最新版に更新されていない。

3. EIDを誤入力している(コピー&ペーストしないと間違えやすいです)。

4. セキュリティソフトにより「疑わしい処理」として遮断されている。その場合は、セキュリティソフトを一時的に無効にしてインストールしてください。

5. ライセンス認証サーバーへの接続ができていない。その場合は、管理者へお問い合わせください。インストール時に(気付かない間に)管理者権限に昇格していたりして、インターネットアクセスに何らかの制限が加えられている可能性が考えられます。インストール時にはインストールマニュアルに記載の Sentinel EMS へアクセスする必要があります。

ログ等を確認しても解決しない場合、オフラインライセンスや従来版ライセンスをご案内する場合がございます。
A Windows Updateを行うと、このようなエラーが起こる場合があります。Ver5.1以降をご利用の方は、スタートメニューから、「MSI Solutions」 → 「S4ライセンス情報更新」 をクリックしてください。エラーが解消しない場合や、Ver5.0以前をご利用の方は、S4 Simulation Systemをアンインストールし、再度インストールしてください。
A インストールの途中で、トラブルが発生し、インストールが途中で中断された場合や、ハードディスクの容量が少ない状態でインストールを行うと、インストールが不完全な状態でS4 Simulation Systemが起動する場合があります。その状態でシミュレーションを実行するとこのエラーが起こります。その場合は、コントロールパネルの「プログラムのアンインストール」より、Python 3.6.6 for MSI productsをアンインストールして頂き、msipython366x64.exe を実行してください。ハードディスクの容量が少ない場合には、容量をあけた後、この作業を行ってください。インストール後、S4 Simulation System を起動し、再度シミュレーションを実行してください。 再度エラーが発生する場合には、「c:\Program Files\Mathematical Systems Inc\Python3」の下の、install-msi-err.log、install-msi.log、install-msi-out.logをS4 Simulation System サポート窓口(s4-support[at]ml.msi.co.jp ※[at]は@に変換してください)までご送付ください。

基本的な質問

A こちらこちらからご覧ください。
チュートリアルは、GUIのヘルプメニューからご覧頂けます。
A S4 Simulation System インストールフォルダの下、samplesフォルダにあります。サンプルプログラムはS4 Simulation System のGUIのプロジェクトメニューから取り込めます(ヘルプメニュー → 操作マニュアル「プロジェクトのインポート」を参照)。
また、こちらから、当Webページで紹介しているサンプルプログラム一式もダウンロードできます(Webページ限定で公開しているものもあります)。
A S4 Simulation System における連続シミュレーションでは、1階の常微分方程式のみ扱う事ができます。それ以外の式に付きましては、常微分方程式の形に変形できるものに関しては、変形して頂いてからS4 Simulation System にその式を設定してください。具体的な入力方法については、「ヘルプ」→「pdf版ドキュメントを表示」→「チュートリアル」の「6.Lotoka-Volterra方程式」をご参照ください。

GUI操作

A 一括実行機能を使うと便利です。下記の通り設定してください。

1. パラメータ設定画面(「モデル」メニュー→「パラメータを編集する」)より、「一括実行」タブにおいて「レプリケーション」の「最小回数」、「最大回数」に繰り返し実行したい回数を設定します(最小、最大に同じ値を設定します)。
2. 「出力」の「+」を押します。列名に繰り返し実行して評価したい値の名前を設定します。
3.「基本設定」タブに切り替えて、一番上の「実行種類」を一括実行に切り替えます。
4. 分析スクリプト設定画面(「モデル」メニュー→「分析スクリプトを編集する」)より、評価したい値のスクリプトを編集します。デフォルトでは、0 が返るようになっていますので、0の代わりに評価したい値を設定します。例えば、分析スクリプト設定画面の Browser に表示されている統計量(平均など)をドラッグandドロップするとスクリプトが自動生成されます。
5. 実行すると、出力フォルダの一括実行詳細結果に結果が出力されています。

一括実行が設定されているプログラムは下記からダウンロードできます。
bank_repetition.s4(Ver5以降)
A 以下のように確認いただけます:
モデル実行後にサマリを表示します。サマリはメニューバーの「Σ」ボタンより表示できます。
「窓口」の「バッファ」行の「平均値」が稼働している窓口の個数の平均値、「容量」が窓口数になります。よって前者/後者を計算いただくことで稼働率を計算することができます。
なお、サマリ画面にこれらの情報を表示させるためには窓口部品の編集画面において、「記録」を「あり」に設定しておく必要があります。
A 1. 出力の関数を複数指定
2. 対応する関数を分析スクリプトで定義
とすることで実現できます。

1. 出力の関数を複数指定
・パラメータ編集画面(「Pボタン」)の一括実行タブにおいて、「出力」の+ボタンを押して、出力の個数を増やします。
・「列名」を任意の文字に変更し、「式」を"self.関数名()"のように指定します。
"self."とカッコが必要であることに注意してください。
関数名は具体的には何でもよく、例えば
self.objective1()
self.objective2()
...
のように指定します。
「列の型」は出力したい値が数値であれば「整数」もしくは「実数」のうち適切な方を、文字列であれば「文字列」を指定します。
2. 対応する関数を分析スクリプトで定義
3. 指定した関数を以下のように定義します。
・分析スクリプト編集画面(「Aボタン」)より、下側の「分析スクリプトを追加」を選択
・スクリプト名の指定を求められるので、1. で入れた関数名(ex. objective1)を入力する
・関数の定義画面に移るので、スクリプトを書くか、右側のブラウザパネルから取得したい値をダブルクリックして編集します。 ・以上を関数の個数だけ繰り返します。

離散イベントシミュレーション

A ファシリティやストアのような資源部品を取得する際に、取得待ちが発生するとき、優先度付きキューを設定しておけば、優先度の高い順番からキューから取得する事が出来ます。これにより、優先度の高いジョブを優先的に機械に投入するというような処理を表現する事が出来ます。
 優先度付きキューのイメージについては、「ヘルプ」→「pdf版ドキュメントを表示」→「操作マニュアル」の「18.1.2 優先度付きキュー」もご参照ください。
 また、優先度付きキューのサンプルプログラムを下記からダウンロードできます。併せてご参照ください。
GUI→「プロジェクト」 →「プロジェクトをインポート」から下記ファイルを指定すると読み込めます。サンプルプログラムの解説は、「モデル」→「カスタムコードを編集する」をクリックすると確認が出来ます。
priorityqueue.sss(Ver5より前)
priorityqueue.s4(Ver5以降)
A アイテムの種類によってファシリティで処理する優先度を変えたい場合は、優先度付きキューを用います。種類ごとにアイテムを用意し、各アイテム属性に種類を表すname、優先度を表すpを定義しておきます。その際、与えたい優先度に応じてnameとpに値を設定しておきます。各アイテムには生成部品をそれぞれ用意し、優先度付きキューでファシリティで処理させるようにしておきます。
 上記のサンプルプログラムは下記からダウンロードできます。
GUI→「プロジェクト」 →「プロジェクトをインポート」から下記ファイルを指定すると読み込めます。サンプルプログラムの解説は、「モデル」→「カスタムコードを編集する」をクリックすると確認が出来ます。
priorityqueue2.sss(Ver5より前)
priorityqueue2.s4(Ver5以降)
A 判断部品では、条件式と出力先を並べることで分岐させることができます。例えば、シミュレーション時刻で分岐させるには、条件式にシミュレーション時刻を取得する now()を用いて条件比較を行います。あるいは、アイテムの種類によって分岐させたい場合には、アイテム部品に属性を設定し、その値で条件比較を行います。例えば、アイテム属性にaという属性を設定した場合、判断部品では、item.a とする事で値を参照できますので、その値で条件比較を行います。尚、判断部品にはデフォルトでは出力先が1つしかありませんが、出力先の個数を増やすには、「共通設定」タブ内の「出力」にある+ボタンを押します。アイテム属性はアイテム部品の編集画面の「属性設定」タブ内の「属性リスト」で指定することができます。
判断部品の使い方のサンプルプログラムは下記からダウンロードできます。
decide.s4(Ver5以降)
A アイテムはGUIで指定した部品の繋がりに沿って移動していきますが、シミュレーションの状況によっては次の部品に移動ができない場合があります(ファシリティを取得できない場合など)。
部品の入力ポートもしくは出力ポートに「キュー」と呼ばれるエリアを設定しておけば、このような場合に一時的にアイテムを貯めておくことができます。
ご質問の「キューサイズ」はこのエリアに入れられるアイテムの個数の上限のことを示します。この値を1以上に設定することでキューを設けることができます。キューが一杯のとき、キューにアイテムを追加しようとする部品の動作は停止します。
通常は、各部品の「入力ポート」にキューを作っておけば、出力ポートにキューを作る必要はありません。
出力ポート側にキューを設ける例としては、その部品の次の接続先が複数ある場合が考えられます。
この場合動作としてはプル型の動作になり、接続先から要求があった際に、キューからの取得操作が発生します。
A 窓口部品の1は窓口が1つ存在することを意味し、窓口の利用部品の1は来たお客さんを1つの窓口でさばくことを示しています。 例えば窓口を2つにしたい場合、両方を2に変更する必要があります。(前者のみ2に変更すると、窓口が2つ存在するが利用されるのは常に1つだけ、という状況になってしまいます)
煩雑のようですが、より複雑な状況(ex. 窓口利用部品が複数個あり、同じ窓口を共有するような場合)を表現したいときにはこれらをうまく設定することで解決できる場合があります。
A 判断部品の式中で
self.parent.rFacility
と書くことでオブジェクト名がrFacilityのファシリティを参照できます。
(ファシリティ部品の編集画面の「共通設定」「オブジェクト名」から確認・変更することができます。)
装置の稼働率は以下のように計算することが出来ます:
self.parent.rFacility.monitor["バッファ"].mean() / (装置の並列数)
以下、単語の説明です。
"monitor"は装置の稼働記録を保持しており、ファシリティ編集において記録「あり」にしておく必要があります。
「バッファ」は使用されている装置の個数で、"mean"というメソッドによって平均を取ることで、時間平均が取られ、「これまでの装置の平均使用数」を求めることができます。
これを並列数(=装置の個数)で割ることで平均稼働率を求めることが出来ます。並列数はファシリティの編集画面より確認できます。
質問に戻りますが、例えば「これまでの稼働率が50%未満かどうか」といった判断であれば
self.parent.rFacility.monitor["バッファ"].mean()/(装置の並列数) < 0.5
のように書けばよい、ということになります。
monitorの扱いについては、言語リファレンスにも記述がございますのでよろしければご参照ください。
A 例えば、判断部品の条件式に、「名前がrFacilityであるファシリティを参照し、それが稼働中であればTrue」とする式を書きたい場合、以下のように書くことが出来ます:
self.parent.rFacility.buffer<0
単語の意味ですが、selfはここでは判断部品そのもの、parentは判断部品を含めた全ての部品を所有しているシミュレータのことを指します。
(多くの部品でこのように "self.parent"と書くことでシミュレータを取得できます)
今回は特に、ファシリティを参照したいのでそのオブジェクト名を繋げて(rFacility)、装置のうち稼働している個数(buffer)を指定しています。
なお"rFacility"はファシリティ部品の設定時に決めた名称で、ファシリティ部品の編集画面の「共通設定」「オブジェクト名」から確認・変更することができます。
補足ですが、逆に「装置が稼働していなければTrue」となる式であれば、
self.parent.rFacility.buffer==0
とすればよいことになります。
A 一般的に、システム内客数はサービスを受けるために並んでいる人数とサービスを受けている人数の合計を指します。S4 Simulation System においては、サービスを受けるために並んでいる人数の変化と、サービスを受けている人数の変化を別々に観測しています。 サービスを受けるために並んでいる人数は、窓口利用部品の共通設定タブの入力ポート1 の「記録」を有りに設定して実行すると、「窓口利用-入力1」というモニターが観測されます。そのモニターのバッファ列が、サービスを受けるために並んでいる人数になります。
この時、サービスを受けるために並んでいる時間は、「窓口利用-ファシリティの記録」というモニターの待ち時間列に記録されています。
また、ファシリティが記録したモニターのバッファ列が、サービスを受けている人数になります。
システム内客数はサービスを受けるために並んでいる人数とサービスを受けている人数の合計ですが、それぞれ独立に観測されているため、システム内客数を観測するためには、タンクオブジェクトを配置しておき、システムに入る前にカウントアップし、システムから出る時にカウントダウンする事で、システム内客数を観測できます。
同様に、システム内滞留時間を観測するためには、システムに入った時間と、システムから出る時間の差を記録する事で、観測できます。
以下のサンプルプロジェクトのタンクが記録したモニターのバッファ列が、システム内客数になります。また、滞留時間モニターの滞留時間列がシステム内滞留時間になります。
この例の場合、
平均到着率 λ(人/秒) = 1 / 60
平均サービス率 μ(人/秒) = 1 / 50
なので、M/M/1 の理論値は、
窓口利用率 ρ = λ / μ = 5/6
平均待ち行列 Q (人) = ρ / (1 - ρ) = 5
待ち時間 W (秒) = ρ / μ = 250
滞留時間 (秒) = ρ / μ + 1 / μ = 300
となります。
ここで、平均待ち行列とは、サービスを受けるために並んでいる人数とサービスを受けている人数の合計であり、先に伸べたシステム内客数を意味します。
また、待ち時間とは、サービスを受けるために並んでいる時間を指します。滞留時間は待ち時間とサービス時間を加えたものになります。
乱数を使ったシミュレーションなので、理論値と正確に一致はしませんが、概ね一致する事を確認できるかと思います。
システム内客数のサンプルプログラムを下記からダウンロードできます。併せてご参照ください。
GUI→「プロジェクト」 →「プロジェクトをインポート」から下記ファイルを指定すると読み込めます。サンプルプログラムの解説は、「モデル」→「カスタムコードを編集する」をクリックすると確認が出来ます。
numberofcustomers.s4(Ver6 以降)
A 1. 外部データの取り込み
csvデータをS4にインポートします
具体的なインポート方法は操作マニュアルP60(4.4 データのインポート)をご参照ください。 2. データ列をシミュレーション設定に反映
取り込んだデータを生成部品の生成時間や1回の生成数に使用します。
a. 生成部品の生成時間に設定するには
生成部品の生成時間において、生成方式を「再生(列指定)」とし、用いたい列をその隣のプルダウンから選択します。
その下にある「生成時間系列の生成」を「初回のみ」に指定します。
これによって、アイテムが生成されるたびに、データを1行ずつ読み込み読み込んだ値が使用されます。
なおオプションとして、「繰り返し」を「あり」に設定すると最後までデータ列を読み込んだときに、最初に戻って値の生成を繰り返します。
(「あり」に設定せずに、データ数より多い回数の生成を行おうとするとエラーになります)
b. それ以外の箇所(生成部品の生成個数、ファシリティ利用の利用時間、など)に設定する方法
以下のように、パラメータを設定し、そこから値を生成することで読み込むことができます:
i. モデルパラメータ編集画面より、パラメータ名"gen"として「再生(列指定」「(使用したい列名)」「ジェネレータを返す」を指定し、パラメータを設定します。
i. 品番設定の部品において、hinbanの値を「ユーザ定義ジェネレータ」「self.param.gen」「値を返す」を指定する

エージェントシミュレーション

A 環境部品の「環境上のエージェントの描画処理」の2行目に以下の記述を追加してください:
screen.text(self.x0, self.y0, str(now()))
(以下はこの構文の説明になります。)
screen.text(x,y,文字列)で画面上の(x(横軸),y(縦軸))位置に文字列を出力することが可能です。
x,yの値を適宜設定し、所望の位置に出力を調整してください。
(画面座標の最小値/最大値は環境オブジェクトが保持しており、
self.x0, self.x1
self.y0, selfy1
のように取得することが可能です。)
日本語を表示したい場合は別途処理が必要になります。
A エージェント部品の「エージェント集合の可視化」のコード内にある
getAgentScreen()関数に対して引数sizeとして(X, Y)を与えることで でウィンドウの横/縦のサイズを指定出来ます。
例えば、下記のようにコーディングしてみてください:
screen = self.getAgentScreen(interval = interval,
xlim = (self.env.x0, self.env.x1),
ylim = (self.env.y0, self.env.y1),
size = (1000, 2000))
A 「エージェント集合の初期化処理」において、generateAgent()関数が呼ばれるタイミングを調整すればよいです。
具体的には、
g = exponentialDistribution(10)
の行もしくはその下の
yield pause(next(g))
の行を変更します。
前者を
g = exponentialDistribution(200)
のようにすれば「平均して200秒に1人」生成します。
また、後者を
yield pause(10)
のように変更すれば「ちょうど10秒ごとに1人」生成します。
複雑な生成間隔(実際の来店記録データの値で生成したい、等)は都度、その値を得るためのPythonコーディングが必要になります。
A S4 Simulation System のエージェントシミュレーションでは
・環境
・エージェント
の2つを作り込んでいくことでシミュレーションモデルを構築していきます。
S4が提供しているAPI(環境やエージェントが持つメソッド)を組み合わせてPythonプログラミングを行うことで様々な機能を実現することが可能です。
具体的には、下記のような資料に目を通すことから始めるのが良いかと思います。
チュートリアル9~11章
→ エージェントシミュレーションの基本的な作り方を紹介しております
psim言語リファレンス3章
→ エージェントシミュレーションで活用できるAPIの解説がございます
操作マニュアル11~13章
→ エージェントシミュレーションに関わるGUI部品に関する説明がございます
よくある例としては、
・屋内の狭い範囲の人の動きを細かくシミュレーションしたい
→ 建物の形状をSFM地図部品のエディタで記述し、経路地点属性などで人の移動経路を指定し、SFMエージェントシミュレーションを行う。
・屋外の比較的広い範囲の、人や車の流れをシミュレーションしたい
→ 写真を背景にNW地図のエディタで経路グラフを作成し、その上に典型的な人や車の移動経路を指定してNWエージェントシミュレーションを行う。
というようなケースになります。
いずれのケースでも、エージェントの細かい挙動はエージェント部品でのコーディングによって作り込んでいくことになります。
上記資料を参考に取り組んでいただけますと幸いです。
A ・エージェント属性の変更
(表示色の変更)
エージェントの初期化処理において
self.screenColor
self.screenEdgeColor
をそれぞれ変更します。
デフォルトでは"b"(青)で、"r"(赤), "k"(黒), "g"(緑)などが指定できます。
その他の指定方法については、matplotlibライブラリの挙動に準じます。
例えば
https://matplotlib.org/3.3.2/api/colors_api.html
https://pythondatascience.plavox.info/matplotlib/%E8%89%B2%E3%81%AE%E5%90%8D%E5%89%8D
などから調べることができます。
(表示サイズ, マーカーを変更)
同様に、self.screenSize(SFM/NWシミュレーションの場合、self.r)の値を変更します。
SFM/NW以外のエージェントシミュレーションでは self.screenMarker を変更することで見た目を変えることができます("+", "x"など)
(不透明度の変更)
self.screenAlpha を0.0~1.0の間で変更することで、透過度を変更することができます。
・可視化コードを直接編集する
環境部品の「環境像のエージェントの描画処理」のコードを編集することで可視化を直接コントロールすることができます。
上記の属性などもこのコード中で参照されているので、エージェント属性を編集する代わりにこのコード部分の値を書き換えることでも同様の変更が可能です。
より細かい制御が必要な場合はこちらの方法を検討ください。
なお、可視化コードに用いられているScreenクラスの仕様についてはpsim言語リファレンス3.6節を参照ください。
A yyyy/mm/dd hh:mm:ss のような形式で時刻を表示させたい、ということであれば、環境部品の「環境上のエージェントの描画処理」の2行目に以下のように挿入することで表示が可能です:
# s: シミュレーション開始時刻
s = self.simulator.start
# (x,y): 表示位置
x = 0
y = 0
screen.text(x, y,(s + datetime.timedelta(seconds=int(now()))).isoformat(sep=" "))
これはS4 Simulation Systemの機能というよりは、Pythonのdatetimeモジュールの機能になります。
A デフォルトで入っているコードは「人口密度d, 最大移動速度v0から移動速度を算出する」ものになっています。
V = np.zeros(v0.shape, dtype=float)
V[d < 1.5] = -0.204 * d[d < 1.5] + 1.48
V[d >= 1.5] = 1.32 * np.log(9.16 / d[d >= 1.5]) / np.log(10)
# K > 9.16 の場合、V < 0 になってしまう。
V.clip(0.1, np.inf, out = V)
return V * v0 / 1.48
速度計算式を変更するにはこれをコーディングにより編集する必要があります。
例えば、単に「決まった速度(毎秒10m、など)で動いてほしい」であれば
return 10
とするだけで良いです。
より複雑に、人口密度によってエージェントごとに速度を変化させたい場合(デフォルトの例はこちら)や、加減速をつけたい場合はnumpyの配列演算を用いたコーディングが必要になります。
詳しくはこちらからお問い合わせください。
A S4 Simulation Systemの機能(モニタ機能)もございますが、エージェントシミュレーションを行う中で既にPythonを記述していらっしゃると思いますので、 Pythonでデータ集計~出力を行うのが早いかと存じます。
例えば、「エージェントの初期化後の処理」で
self.data = [] # 毎時刻覚えたい値
のようにリストを定義し、 「エージェントのステップ処理」で
self.data.append((now(), value)) # valueは覚えたい値
として時刻と値のペアを記録していきます。
そして同じく「エージェントのステップ処理」の最後において if now()==1000:
import pandas as pd
df = pd.DataFrame(self.data, index=["time", "value"])
df.to_csv(出力パス)
とすることで指定したパスにcsvファイルが出力されます。
(出力時刻を1000としていますがここは適宜編集ください。)
CSVの出力のためにPythonのpandasモジュールを使用しています。 こちらのリファレンスについてはWeb上に説明が豊富にございますのでそちらを参照ください。
ex.
https://pandas.pydata.org/docs/reference/index.html#api
A SFM:
歩行者同士・歩行者と障害物の間に反発力を入れたモデル。
歩行者が互いを避けながら目的地に向かうシミュレーションを行うことができます。
狭い範囲で精緻なシミュレーションを行いたい場合に適しています。
計算速度の制約から、エージェント数は500程度が限界です。
NW:
人の移動を単純化して、グラフのエッジ上を移動するモデル。
SFMのような人の反発は表現しませんが、エッジの混雑具合に応じて移動速度を変える、といった表現は可能です。
設定を行えばエッジの混雑度が上限を超えるとエージェントが停止し、それが伝搬する様子(渋滞)を表現することも可能です。
動かすだけであれば数万以上のエージェントを同時に扱うことが可能です。
A エージェントは固有のIDをagentidという属性名で保持しています。
エージェントの(初期化処理やステップ処理の)編集コードであれば
self.agentid
としてアクセスすることが可能です。
補足ですが、その他にどのような属性があるのかについてはpsim言語リファレンスのエージェントの章(3.4節)からご覧いただけます。
psim言語リファレンスはS4 Simulation Systemのメニューバーのヘルプ→pdf版ドキュメント、からもご覧いただけます。

SFMエージェントは、以下の属性を持ちます:
p 現在地
A 相互作用の強さ(N)
B 相互作用の範囲(m)
v0 最適速度(m/s)
v1 最高速度(m/s)
r 歩行者の半径(m)
tau 加速時間(s)
m 体重(kg)
c 外力の変動係数
visR 視野制限距離(m) (0 以下で制限なし)
visTheta 視野仰角(degree)
method 経路計算方法(「TIM」「CMM」「PGM」から選ぶ)
stayType 滞留時の動作("out", "float", "fix", "return"から選ぶ。詳細はSFM 環境の引数リストを参照) また、エージェントが向かっている目的地点を取得したい場合は、
v = self.state.G
として経路地点番号を得ることができます。
この経路地点に関してさらに情報を得たい場合は経路グラフオブジェクト
p = self.env.pathgraph.node[v]
としてこの経路地点の情報(x,y座標値, 地図エディタで与えた属性)を持つPythonの辞書型オブジェクトを取得することができます。
A エージェントシミュレーションであれば環境のsimulator属性、
離散イベントシミュレーションであれば各部品のsimulator属性によってシミュレータオブジェクトを取得することができます。
このオブジェクトはシミュレーション全体に関わる情報を保持しており、以下のような属性を持ちます:
・inputDir: 入力フォルダ
・outputDir: 出力フォルダ
・dataDir: シミュレーション内部で使用されるデータ(地図エディタで作った地図など)が配置されるフォルダ
・start: GUIで設定したシミュレーション開始時間
・until: GUIで設定したシミュレーション終了時間
・warm: GUIで設定したウォームアップ時間
・param: GUIのパラメータ設定で指定したパラメータ。例えば"hoge"という名称のパラメータを設定していれば param.hoge としてこのパラメータにアクセスすることができます。
例えば、エージェントシミュレーションで「エージェント集合のステップ処理」においてシミュレーション終了時刻を取得したい場合は
self.env.simulator.until
のように記述します。
A 以下の方法でSFMモデルにおけるエージェント同士の干渉の強さを制御することが可能です:
SFM環境orSFM地図部品の編集画面において「相互作用の距離(m)」を小さくする(ex. 0.001など。0にするとエラーになります)
エージェントの半径を小さくする
エージェント半径はデフォルトでは環境部品の編集画面の「歩行者半径」の値が使われますので、ここを編集するか、エージェント生成時に渡している引数を変更ください。
ただしエージェント半径を変更しますと描画時のエージェントサイズも小さくなってしまいますので、適宜「環境上のエージェントの描画処理」においてagent.rを参照している箇所を書き換える(何倍かして見た目だけ大きめにする)必要があるかもしれません。
そもそもエージェント同士の干渉まで再現する必要がない場合、NWシミュレーションの利用もありえます。
NWシミュレーションはSFMシミュレーションの地図部品、エージェント部品をNW地図、NWエージェントに差し替え、経路グラフや各種コードをコピー・ペーストするだけで移行することが可能です。