効率的なバスローディング


10

これはずっと前にバス旅行会社でやったことで、結果に満足することはできませんでした。私は最近、その古いプロジェクトについて考えていて、その問題をもう一度見たいと思いました。

問題:

バス旅行会社には、乗客定員が異なる複数のバスがあります(50人の乗客のバス15台、30人の乗客のバス25台など)。彼らは非常に大きなグループ(グループあたり300人以上の乗客)への輸送を提供することに特化しました。各グループは一緒に旅行する必要があるため、無駄を減らすために艦隊を効率的に管理する必要がありました。

たとえば、88人の乗客は、2人の50人乗りのバス(12人の空席)よりも3人の30人乗りのバス(2人の空席)でよりよくサービスされます。別の例では、75人の乗客は、1つの50人の乗客バスと1つの30人の乗客バス(種類の混合)でよりよくサービスされます。

これを行うための良いアルゴリズムは何ですか?


3
うるさいというわけではありませんが、バス会社の観点からすると、ガス代は3ではなく2バスにしか行くことがないので、2台の50旅客バスの方が効率的でしょう。
ダンク

8
これは、NPハードであるナップザック問題のように聞こえます。実際には、特定のルートの検索スペースはかなり小さいはずです。
chrisaycock

@ダンク-バスとツアーのロジスティクスについてまったくわからないことを認めるのは私が最初です、それ彼らの要件でした。彼らは手作業でそれをした高給のコンサルタントさえいた。
システムダウン

空席は関係ありません。重要なのは運用コストです。したがって、哲学者の答えを見てください。
Loren Pechtel

@LorenPechtel-前に言ったように、私はビジネスルールを指示するのではなく、実装するだけです。
システムダウン、

回答:


8

これは、(一種の)ビンパッキング問題の例であり、ナップザック問題とよく混同されます。ビンパッキングでは、特定の容量のビンがあり、さまざまなサイズのオブジェクトをビンに分散しようとしています。アイデアは、可能な限り少ない数のビンを使用することです。

ビンの数を最小限に抑えようとしているわけではありませんが、空のシートの数を最小限に抑えようとしています。また、フリート全体の空席の数を最小限に抑えようとしている可能性があります。つまり、さまざまなサイズの4つのツアーグループがあり、空席の数が最も少ないすべてのグループに対応したいとします。私はすぐにインスタンスを考えることはできませんが、フリートとツアーグループのセットを構築して、一部のグループでは標準以下のソリューションを使用することで回避できるので、それが可能になると思います他のグループにはさらに悪い解決策を使用します。

悪化する。20、30、50の旅客バスがある場合はどうでしょう。燃料の使用量はそれぞれ異なりますが、20と30を実行するよりも1つの50を実行する方が効率的です。しかし、私たちの単一の測定(空のシートの最小数)から、50のどちらかを実行することは理にかなっています旅客ツアー。

また、28や39のような奇妙な番号のバスは、多くのショートカットを歪めます。

したがって、状況の複雑さに応じて、次の2つのいずれかを実行できます。

まず、徹底的な検索ツリー:バスの可能なすべての組み合わせを使用します。バスサイズが3または4しかない場合、これはおそらく妥当な解決策です。そうでなければ、最適フィットの減少のようなものが妥当な結果になりますが、最適ではありません。


なぜこの回答が反対票を投じられたのかは想像できません。補償する賛成票。よくやった。
David Conrad

1

Pythonでの簡単なソリューションは次のとおりです。

def add50(passengers, buses):
    proposed = buses + [50]
    if sum(proposed) < passengers:
        return add50(passengers, proposed)
    return proposed

def add30(passengers, buses):
    proposed = buses + [30]
    if sum(proposed) < passengers:
        proposed30 = add30(passengers, proposed)
        proposed50 = add50(passengers, proposed)
        return proposed30 if sum(proposed30) < sum(proposed50) else proposed50
    return proposed

print add30(88, [])
print add30(75, [])
print add30(105, [])

実行すると、次のようになります。

[30, 30, 30]
[30, 50]
[30, 30, 50]

コードは、考えられるシナリオ全体で縦型検索を行っています。順序は関係ないので([30, 50]と同じです[50, 30])、同じサイズ以上のバスを追加するだけで、検索スペースを大幅に小さくすることができます。これadd30()がを呼び出すことができる理由ですがadd50()、逆はできません。


0

これをお客様の視点からお答えします。このアプリケーションにハードコーディングされたアルゴリズムは必要ありません。時間の経過とともに変化する可能性のある変数が多すぎます。バスについては何も変更されない可能性がありますが、要因の重みが変更されたり、私が思いもしなかった新しい要因が発見されたりする可能性があります(例:時間外、法律、その他の運転手費用)。

このため、要求された乗客数の範囲に基づいて独自のルックアップテーブルを作成したいと思います。また、最適なバスの組み合わせのために独自の設定を作成します。例:31-50 = 1 X 50、51-60 = 2 X30。これは本当に計算する必要がありますか?シート、ガス、ドライバーを考慮した数式の束よりも設定を変更する方が簡単です。最適な組み合わせを見つけ出し、それを使用して、ユーザーが適切と考えるようにこれらの設定を変更するための十分な余地を持っています。

新しい要素が発見される可能性があります。大型のバスは料金に指数関数的に高い料金を支払いますか?30人を超える乗客のバスの運転手に追加の認証とライセンスの新しい法律が施行された場合、小型バスのより安価な運転手を取得できますか?

彼らは彼らの公式とは異なるロジックを持つ新しいコンサルタントを雇い、あなたのアプリは書き直される必要があるかもしれません。あなたは駐車場のコストを考慮に入れなければならないということですか?


これは機能しません。31-50= 50座席バスです。ただし、他のグループで既に使用されている場合や、サービスが停止している場合、または他の理由で利用できない場合を除きます。問題のバス会社は、15人の50人乗りのバスで、一度に複数の顧客がいる可能性が非常に高いです。
MSalters 2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.