プラレールの複々…線化を、数理最適化を使って考える

プラレール

複線レールがあるとおり、プラレールにおいて複線までは考慮されています。しかし、3線以上の並行までは考えられておらず、それ用のレールの販売もされていません。複線外側曲線レールより大きいレールとして大曲線レールがかつて販売されていましたが、複線外側曲線レールの外側に置くには若干小さい寸法です。

そこで、既存のレールを組み合わせて3線以上の曲線レイアウトを作成することとなります。ここでの問題は、1/4直線レールの長さが54mmであるのに対し、複線幅は60mmと若干の誤差があることです。そのため、3線以上の曲線部分は「多少の誤差はレールの柔軟性でごまかす」、いわゆるなじませつなぎが基本となります。

各地のイベントなどで設置される3線以上の曲線レイアウトは、このなじませつなぎを前提とし、経験に基づいてレールを組み合わせることで表現されてきました。しかし、それが最適な組み合わせであるのかという検証は行われていません。

本記事では、3線以上の曲線レイアウトを作る際に最も寸法の誤差が小さいレールの組み合わせを、経験則や現実の試行錯誤ではなく、数理最適化の手法を用いて求めました。

完全に論文のノリになってしまった。やめたやめた。

考え方

本記事では、曲線レール2本分すなわち90°カーブを4回繰り返すようなオーバルレイアウトの、90°カーブ部分を考えます。3L-nS-1L-nS-3L-nS-1L-nSのようなひし形のレイアウト、その他は考えません。めんどくさいので。

要は、以下の空白部分にレールを敷く場合、レールをどう組み合わせれば最も誤差が小さくなるのかを数学的に考えます。

複々線カーブの画像

使用するレールは曲線レール・複線外側曲線レール・直線レール・1/2直線レール・1/4直線レールの5種類です。

曲線レール・複線外側曲線レールは合計2つ使用し、S字などの特殊な形状は考えないこととします。

直線レールと曲線レールは、位置によって縦・斜め・横、縦側・横側と呼んで区別します。

各レールを使用した際の縦・横移動量は以下の通りです(小数点以下四捨五入)。

レール種別縦移動量 [mm]横移動量 [mm]
曲線レール(縦側)15363
曲線レール(横側)63153
複線外側曲線レール(縦側)19581
複線外側曲線レール(横側)81195
直線レール(縦)2160
直線レール(斜め)153153
直線レール(横)0216
1/2直線レール(縦)1080
1/2直線レール(斜め)7676
1/2直線レール(横)0108
1/4直線レール(縦)540
1/4直線レール(斜め)3838
1/4直線レール(横)054

実装

Python+PuLPで実装しました。ポケGO最適化の名残…。

ソースコードは以下に置いてあります。増えたらGitHubに移行するかも。

MultipleTrack.py
GitHub Gist: instantly share code, notes, and snippets.

ライブラリの都合上、普通の二乗誤差の最小化は無理だったので、min(縦方向の寸法誤差, 横方向の寸法誤差)で実装しています。

結果

内側から1線目のカーブは
曲線レール×1本+曲線レール×1本
で作れます(縦方向誤差 0 mm 横方向誤差 0 mm)

内側から2線目のカーブは
複線外側直線レール×1本+複線外側直線レール×1本
で作れます(縦方向誤差 0 mm 横方向誤差 0 mm)

内側から3線目のカーブは
曲線レール×1本+1/4直線レール×3本+曲線レール×1本
で作れます(縦方向誤差 6 mm 横方向誤差 6 mm)

内側から4線目のカーブは
1/2直線レール×1本+曲線レール×1本+1/4直線レール×2本+曲線レール×1本+1/2直線レール×1本
で作れます(縦方向誤差 -4 mm 横方向誤差 -4 mm)

内側から5線目のカーブは
1/4直線レール×3本+曲線レール×1本+1/4直線レール×2本+曲線レール×1本+1/4直線レール×3本
で作れます(縦方向誤差 2 mm 横方向誤差 2 mm)

内側から6線目のカーブは
1/4直線レール×2本+曲線レール×1本+直線レール×1本+1/4直線レール×1本+曲線レール×1本+1/4直線レール×2本
で作れます(縦方向誤差 1 mm 横方向誤差 1 mm)

実際に作ってみた

3線目と4線目。なじませつなぎ感がかなりあります。

5線目と6線目。きれいにつながってますが、重なってます。

なぜ3・4・5・6線目を同時に作らないかって? 1/4直線レールが足りないからですよ…。

おわりに

厳しめななじませがあったり、レール同士が重なったり、現実はなかなかうまくいかないですね。モデリングが雑すぎたともいう。

反省点としては、そもそも直線レールと1/2直線レールは1/4直線レールで表現できるのでプログラム上は不要だったことに、プログラムを作って走らせて実際にレールを組んでから気づきました。振動して収束しないなんてことになったわけではないので、まあこのままでもいいでしょう多分。

今回は上に書いたとおり min(縦方向の寸法誤差, 横方向の寸法誤差) の実装でした。プラレールの構造上、圧縮伸張方向よりも角度のズレのほうが吸収しやすそうなので、min(カーブの始点から終点までの距離 + α×寸法の縦横誤差) を最小化するといいのかなとぼんやり思っています。係数のαは試行錯誤で決定する感じで。

また、大曲線レールやジョイントレールなどの廃盤レールも含めればもうちょっと幅が広がるかもしれませんね。

ちなみに複線直線レールが4本しかなかったので画面外はこんな感じで頑張っていました。

プラレールの全体写真

コメント