鉄道と工場デザイン
しばらく放置してましたが最近また復帰したので、久しぶりに更新します。
今回は遠距離運送の基本となる鉄道ネットワークらへんについて考えます。(試行錯誤中なのでまだまだ変わると思いますが。)画像が多くなってしまいましたすみません。
碁盤型vs直通型
工場の規模が大きくなるにつれて、アイテムの運送は列車で行うのが主になります。
線路の敷き方には大きく分けて、幹線を張り巡らせる方法(碁盤型など)と、列車を往来させる工場同士を直接結ぶ方法(直通型)の二通りがあります。
それぞれのメリットとデメリットについて考えてみました。
碁盤型
メリット
- 拡張性がある
- 美しい
- 計画しやすい
- 迂回ルートが多くある
- 同時走行できる列車の容量が大きい
デメリット
- 交差点が増える
- 巨大なスペースが必要
- 無駄な線路が多い
直通型
メリット
- 往来が早い
- 交差点が少ない
- 省スペース
デメリット
- 見た目が汚い
- 同時走行できる列車の容量が小さい
- 拡張性があまりない
往来の遅さは本数を増やすことでカバーできるので、ぼくは碁盤型の工場を作っています。
汚くてごめんなさい。でかいのはソーラーパネルです。
幹線のデザイン
幹線は上下線それぞれ2車線で十分かなと思います。(勘です)
通常思いつく線路の向きは左側2本が上り、右側2本が下りといったデザインですが、左から順に上り、下り、上り、下りというように、交互にしたほうが交差点で進行を妨害する数が少なくなるみたいなのでそうしました。(その代わり交差点以外での車線変更時に別の車線を跨ぐ必要があります)
工場の形
各工場はひとマスの中でひとつのアイテムを製作するように作っています。集積回路みたいなイメージ?なんですが。
列車の混雑を避けるために、別の工場の出入り口がぶつからないよう工場を回転させて配置させているので、同じ形の工場でも向きが違ったりします。
また燃料を積んだ列車を一本、各工場の搬入口に走らせ、すべての列車が工場の搬入駅でついでに燃料補給ができるようにしています。
搬入口のデザイン
搬入口は荷卸し駅及び、それと同じ数の待機駅、燃料駅からなります。搬入口にやってきた列車はまず待機駅に入り、折り返して荷卸し駅へ、空になると荷物を補給しに別の場所へ向かいます。
列車の細かい制御には回路を使っています。以下はその説明。
回路を使わないと困ること
- いちばん近い駅に入ろうとするので奥の駅のチェスト(バッファ)の残量がなくなりやすい。
- 待機駅まですべて列車で埋まっているのに、新たな列車がこの工場に侵入しようとしてしまうことがある。
これら(主に2番)をどのように解決すればよいかを考えるために、次のことを調べました。
列車の経路選択アルゴリズム
Factorioの列車の経路探索のあれこれは思ってたよりも複雑でした。今回の記事で参照した仕様について一部ピックアップします。(間違ってるかも)出典は公式ウィキです。*1
経路探索では、まずスケジュール中の名前にマッチする無効でない駅を列挙し、A*アルゴリズムにより最もコストが小さい経路を選出します。
- 基本コストは駅までの道のり。(レールの中央線の長さ)
- 別の列車があるブロックには 2*(ブロック長)/(そのブロックまでの距離) のペナルティコストを加算(つまり、遠い場所にある場合はほとんど影響がない)
- 回路により赤信号に設定されているブロックには1000のペナルティコストを加算
- 別の列車が停車している駅が経路に含まれる場合、500のペナルティコストを加算
つまり、待機所が埋まっているのに新しく列車が来てしまうのは、別の空いている待機所が遠すぎて、近くの空いていない待機所のほうがコストが小さいせいだということのようです。待機所がフルの時になるべくペナルティコストが課されるように回路で制御すれば、別の空いている同名駅へ向かってくれるというわけです。
回路で実現していること
簡単に説明すると、次のように回路を組んでだいたい解決しました。
- チェスト(バッファ)の残量が多い(荷卸し)駅を無効にし、少ない駅に優先的に入るようにする。すべての駅が無効になると、すべての駅を有効にする。
- 待機駅がすべて列車で埋まったとき、信号を赤に変えて新たな列車の侵入を禁止する。(+1000ペナルティ)ただし、燃料補給列車が近づくと信号を青に変えて侵入を許可する。さらに待機している列車は荷卸し駅が空くまで発車しないようにする。(+500ペナルティ)
具体的にどう回路を組んでるかは説明すると逆にややこしくなりそうなので、画像だけてきとうにポポポンと貼っておきます。がんばって解読してください。
追記:しばらくこの構造を使っていたのですが、工場を大きくしていくうちにペナルティに対して距離が大きくなりすぎてうまく働かなくなりました。代わりに、「停車中の待機駅を無効化するだけでよくない??」ってことに気づき、今はそれに置き換えています。(簡単に解決できました。)
現状思いつく問題点
現在、荷卸し駅+待機駅の数だけ列車を走らせてるのですが、例えば4つの荷卸し駅のうち3つが無効化されていて、有効な1つに列車が停車、待機駅が満車の場合、満車にもかかわらずこれらの駅にいない3つの列車がここに向かってしまうという問題があります。解決するには、1の解決策を次のように改変する必要があります。
- チェスト(バッファ)の残量が多い(荷卸し)駅を無効にし、少ない駅に優先的に入るようにする。列車が停車していないすべての駅が無効になると、すべての駅を有効にする。
追記:次回の記事にて少し異なる方法で解決しています。
搬出口のデザイン
搬出口もだいたい搬入口と同じですが、燃料の補給は行わないのでいくらか簡単です。
こちらの積み込み駅では、荷卸し駅とは逆に一定以下のバッファしかない場合に駅を無効化しています。
まとめ
最初は戸惑う信号の仕様とかすっ飛ばして経路探索アルゴリズムのこととか書いてしまいました。信号の置き方とかも記事にしようかなと思ったんですが、使っていくうちに理解できるんじゃないでしょうかどうなんだろう。
公式ウィキを読んで鉄道のいろいろを理解するのが鉄道ネットワークマスターへの近道だと思います。(鉄道のページは日本語訳されていますが、残念ながら経路探索アルゴリズムのページの日本語版はまだないです)
次またネタがあれば更新します。モチベにもなるしネタにもできるので良ければコメントくださいませ。