himeshi’s blog

Simutrans本体改造まわりのお話をつらつらと

自動車プレイはむずかしい

この記事はSimutrans Advent Calendar 23日目のエントリとして書かれたものです。

adventar.org

本日はシムトラ学会冬大会にも登壇します。よろしくお願いしいます。

twipla.jp

 自動車プレイについては第一回シムトラ学会でいくらか考察しましたので今回の記事はその続きです。まずは動画を観て復習してみましょう。(6:30あたりぐらいまで)

www.youtube.com

自動車をうまく活かすためには分散交通が必要であるという話をしました。今回は輸送網全部を自動車で組み立てることを考えます。

 

まず大前提となるのが「幹線」を作ってはならないということです。ここでいう幹線とは幹線路線のことで、幹線道路ではありません。自動車プレイで一番問題になるのは1つの停留所に車が集中することで、停留所に車が集中するとバイパス建設でトラフィックを逃がすというアプローチも取れませんし、鉄道に比べて停留所容量も小さくなりがちなのですぐにオーバーフローします。結局容量的に一番問題になるのは停留所なので、停留所に停車しなければその道路に与える負荷は比較的小さくなるといえます。

現実の自動車交通はそのほとんどがマイカーで、マイカーはスタートからゴールまで一切途中停車をせず、乗り換えをしなくて済む交通を実現します。途中停車をしなければ道路に与える負荷は小さくなりますし、(道路さえ上手に建設すれば)一点に車が集中して混雑することを避けられるので理想的には全てのバス停を1対1で直接結ぶようにすればほぼマイカーによる交通と同じような状態になり、分散交通が達成されます。

しかし単純にこの方法を実現するとマップ内停留所数をNとしたときに路線数はN(N+1)/2になります。つまりおよそNの2乗の比例します。例えばマップ内に500の停留所があるとするとおよそ12万5000の路線を用意しなければなりません。そんなことは不可能ですし、もし仮に機械的に実現して1路線に1台のバスをあてがっても明らかに輸送力過剰です。実際の感覚としては、路線数はO(N)(Nに比例)に抑えたいところです。

 

ここでそもそも自動車プレイが本当に可能であるかを理論的に検証してみましょう。実際のシムトラは極めてシステムが複雑であるため、今回は単純化した以下の問題を考察してみます。

  • マップ内に停留所はN個ある。路線はN路線設定できる。
  • 任意の路線について、その路線は道路交通量Tを専有する。(例:路線Aは16本/月。路線Bも路線Cも16本/月の本数で運行する。)
  • 1停留所に乗り入れられる路線はk個以下である。(停留所容量)
  • 1路線で停車できる停留所はh個以下である。(路線容量)
  • ある停留所を起点として、任意の停留所へ乗り換えナシで行けるようにする。すなはち任意の停留所sに対して、sに乗り入れる路線y1, y2, ..., ynが接続する停留所を全て合わせればマップの全ての停留所が含まれるようにする。

この条件を満たしながら、各停留所に路線を割り当てていく。これは制約充足問題であり、解が存在すればその解の通りに路線を設定すればよく、解が存在しなければそもそも自動車プレイはどのようにしても最終的に破綻すると結論付けられる。

ここでkとhについて考察しよう。停留所の道路容量をCs、1路線道路占有交通量をT、区間最大輸送量(ある路線の中で最も混雑する区間の輸送量)をL、1停留所あたりの需要をD (<L)、使用するバスの1編成定員をαとする。
k=Cs/T である。
hについては少し考える必要がある。ある路線は停留所α-β-γ-δの順に接続しているとする。αからδに向かうバスにおいて、もしα, β, γで乗った客が全てδを目的地にすれば最も効率が悪いといえる(途中で客が降りてくれればその分追加で客が乗れるが、この場合は途中で一人も客が降りない)。この時L, h, Dは L>(h-1)Dの関係を満たせば(簡単な図を書いていただければわかります。)条件として十分である。すなはち h<(L/D)+1 である。

もちろんhに関するこの条件は多分に過剰で、任意の停留所から任意の停留所へ乗り換えナシで行けることが保証されている状態で目的地が路線の終端に集中することは考えにくく、また1停留所には複数の路線が乗り入れているため1停留所あたりの需要Dが全てある特定の1路線に集中するとは考えにくい。

ともかく、非常に大胆な近似を行ったものの停留所数N、許容路線数N、停留所の道路容量Cs、1路線道路占有交通量T、区間最大輸送量L、1停留所あたりの需要をD、バスの1編成定員αという既知のパラメータで問題を定義できたわけで、あとは適当な値を入れてどのような条件で制約充足問題が解けるのかコンピューターに解かせればよい。アルゴリズムとしてはTMS(Truth Maintenance System)による推論法や、GA(遺伝的プログラミング)が考えられる。意欲ある方はぜひプログラムを実装し、様々なパラメータで結果を見ていただきたい。

 

難しい話になってしまいましたがたとえ解が存在したとしてもそれはコンピュータで求める他なく、人間がなせる技ではないのでここからは私が「人間がsimutransをするための方法論」として実際に試したロジックとその結論をお話します。

今回試したのは以下のようなプレイ方法です。

  • マップを5~7個のゾーンに分ける
  • 各ゾーン間を乗換なしで移動できる直通の系統を設定する。
  • ゾーン間路線は2ゾーンを直接結び、他のゾーンを経由するとしてもそのゾーンには一切停車しない。
  • ゾーン内のどの地点からでも1回の乗り換えで全てのゾーン間路線にアクセスできるようにする。
  • ゾーン間路線が混雑してきた時は
    ・ 1つの路線系統を複数に分割する(長距離普通列車を短距離普通列車と長距離快速列車に分割するのと一緒)
    ・ 接続するゾーン内で既存路線とは別の場所を走る路線を設定する
    ことで対処する。

このような方針で行けば無用に路線数が増えることもなく、ゾーンAからゾーンBに行く客は必ずゾーンA-B接続路線を利用し、客が増えても無理なくスケールアップができると考えました。

とりあえず下のような256x256のマップを作りました。

f:id:himeshi:20171213142850p:plain

先ほどの方針に従ってマップをA~Eのゾーンに区分し、各ゾーンを直接結ぶ路線を整備(5ゾーンなので5×(5+1)/2=15路線)し、各ゾーン内路線はそのゾーンから発着する全てのゾーン間路線に直接接続するようにしました。

結論を言うと、初期はうまくいっていましたが開発中期になると早速破綻しましたorz

  • ある程度開発が進むと道路信号を使う必要が出てくるので運転間隔がどうしても乱れる。停留所は鉄道プレイでの駅設備に比べて容量が小さいので、旅客取扱量が大きいゾーン間路線で旅客が乗り換え地点で溢れ、特に問題になる。
  • ゾーンX内にある全ゾーン内路線を、ゾーンXに発着する全ゾーン間路線に接続させることは容易ではない。ゾーン内路線規模が大きくなるほどどうしても取りこぼし(一部のゾーン間路線にしか接続できない)が発生する。
  • やっぱりハブ&スポークスに毒されているのでいろんな系統を1箇所に集めがち
  • ゾーン内での旅客発生分布は一様ではない(市役所の近くはその他のエリアに対して著しく旅客発生量が多い)ため気がついたら複数のゾーン間路線が1本の道路・1箇所の停留所に集中する。
  • ゾーン間路線に(市街地での)速達性を持たせるとRoute Costの関係で旅客が好ましくない経路を取り始める。

最後の話についてもう少し詳しく説明します。例えば下の図のような場面を考えましょう。

f:id:himeshi:20171216091101p:plain

 スタートからゴールに行く時、乗換なしで行く経路はありませんが1回乗り換えで行ける経路は2つあります。人間なら普通市内線を経由するルートを選ぶでしょう。しかし途中止まる停留所の数は都市間線経由の方が少ないためsimutrans standardでは市内線は使われず都市間線に旅客が集中することになります。

結局このプレイスタイルで一番ネックになっているのはroute costなので所要時間予測でルートが決まるextendedならもう少しうまくいくのかもしれません。standardのRoute Cost方式だと、経路数がある程度増えた場面で短絡線を作ると意図しないRoute Costの変動があり、思わぬ路線に旅客が集中することが珍しくありません。

 

ちなみに航空プレイをするとこの問題はもっと深刻になります。例えば下の図のように空港Xから空港Yを目指す場面を考えてみましょう。XからYへの直通路線は存在しないのでAまたはBを経由することになります。 A経由でもB経由でもRoute Costは同じです。ではどのように経路選択されるのでしょうか?

f:id:himeshi:20171216092706p:plain

これについては既に128Na氏が分析しています。

simutrans128.blog.fc2.com

乗換え回数が同じ場合は駅の詳細に表示される「出発駅から運行されている駅」で上にあるものが選ばれるとの結論が導かれています。挙動を見る限りこの説は正しそうなのですが、同記事の中で主張されている「出発駅から運行されている駅の表示順は経路の固有のIDで決まっている」には疑問を感じます。少しソースコードを眺めてみたのですが、そのような処理をしている記述は全く見当たらないからです。また経路の固有IDで決まっているなら路線を作る順番を変えることで表示順を操作することが可能なはずですが、実験したところうまくいきませんでした。

ともかく大事なことは、乗換回数が同一の経路が複数ある時その経路は内部のパラメータによって決定され、プレイヤーは操作できないということです。

よってXからYへの経路は1意に定められます。仮にそれが内部パラメータによって空港A経由になったとしましょう。ところが今度はYからXへの経路について、内部パラメータによって空港B経由になるということが生じます。すると、X-Y間の旅客についてX→YはA経由、Y→XはB経由となるので、いわゆる片側需要に苦しめられることになります。

コレを逃れるために「片側需要が発生したら直通路線を設定する」といったことをしてもそれは別の2空港間の経路について同じ現象を発生させるので片側需要の発生は更に悪化します。結局全ての空港間について直通路線を設定するしか無いのですが、はじめに整理したように路線数が空港の数の2乗オーダーになりますし、小空港にとっては明らかに供給過剰です。

 

もう・・・Extendedに乗り換えようかな・・・

 

余談: Simutrans Advent Calendar 2017開催にあたって

せっかくなので主催として少しコメントさせていただきますです。

私が通う大学の学科では毎年アドベントカレンダーを開催する習慣があり、適したネタが無いのでそこに書くこともできずせっかくなのでSimutrans界隈にも持ち込んでみました。比較的早い段階で全日程が埋まる盛況ぷりで嬉しい限りです。

従来日本のシムトラ界隈はもっぱらアドオン作製と動画投稿が主流でそれ以外の情報発信は盛んではありませんでしたが、本来シムトラは非常に多岐にわたる派生分野を持つゲームであり、その発信がアドオンと動画だけに限定されているのはあまりにもったいないと感じていました。そこでプレイスタイルや本体開発、アドオン方面においても制作面の話ができるような場として5月にシムトラ学会を提唱し、開催していただきました。(言い出しっぺが運営やらなくてごめんなさい)

シムトラ学会は非常に有意義なものになりましたが、一方で他の媒体で発信したほうが適している分野の存在も感じ、パッチゼミやアドベントカレンダーと発信機会の多角化を進めました。シムトラ学会の場合直接対面で深い議論が期待できる反面、どうしても時間や距離の制約で参加できるメンバーが限られたり人前で発表することが苦手な人にとってバリアになります。そんな方々にとってアドベントカレンダーが発信の機会になれたなら嬉しく思います。

2018年はどれくらいシムトラできるかわかりませんが、今後も皆さんのお力をお借りしながら本体いじりを通じてシムトラをもっと素晴らしいゲームにしていけたらと思います。それと同時にシムトラのコミュニティがこれまで以上に活性化できるようほそぼそと活動を続けたいと思っております。

それでは皆様よいお年を。