できるだけ少ない箱で商品の最高の宿泊施設を提案する配送見積もりを作成するタスクを受け取りました。
既知の四角形のボックスサイズの有限セットがあります
箱の中に詰められる多くの任意の長方形のアイテムがあります
使用するボックスの数は少ないほど最適です。 2つの箱1x1x1を発送するのは、1つの箱1x2x1よりもはるかに高価だからです。これがここでの優先事項です。
また、第2レベルの優先順位として、可能な限り小さいボックスを使用するように最適化する必要があります。 (例:1つの大きなボックスと2つの小さなボックスから選択できる場合は、大きなボックスを選択する必要があります)
アイテムを回転させてボックスに合わせることができますが、回転は最低でも45°の増分に制限する必要があります(私の研究では、一部の構成では、45度の回転により、より大きな長方形のボックスの内側に長方形のボックスをよりよく収めることができるようです) 、90°回転であることを標準としています。
ボックスには重量制限があり、アイテムには任意の重量があります(例:サイズが1x1x1のアイテムは他の2x2x2アイテムよりも重い場合があります)
私は少し調べて、ビンパッキングとナップザック問題に関するいくつかの抽象化されたアルゴリズムを見つけ、最適なアルゴリズムと同様に、次のような強引なバリエーションを用意しました:
「パックするアイテム」リストで、アイテムを降順のボリューム順に(大きいほうから)並べ替えます。
このリストの各アイテムについて:
「使用済みボックス」リストにあり、アイテムに適合するのに十分な残りの体積と重量の制限がある小さいボックスを選択します(ここに適合とは、寸法と重量に合わせることを意味します)
そのような箱がない場合は、可能な箱サイズの既知のセットから新しい箱を作成します。これは、アイテムの寸法と重量に合う最小のサイズであり、「使用済み箱」のリストに追加します。
ボックスが項目に収まる場合(以下のフィッティング機能を使用)、「このボックスの項目」のリストに追加し、「収まる項目」リストから削除して、ボックス内の相対的な3D位置をマークします。
「梱包するアイテム」リストに適合するアイテムがなくなるまで、2.1から繰り返します。
上記のステップ2で使用されるフィッティングチェック関数:
ボックスの残りの容量がアイテムの容量と一致しているかどうかを確認します。そうでない場合は、falseを返します。
「ボックスのアイテム」の重量と現在のアイテムの重量の合計がボックスの重量制限以下かどうかを確認します。そうでない場合は、falseを返します。
「ボックスのアイテム」リストを確認して、最小のYコンポーネントを持ち、アイテムの幅、奥行き、高さに十分なスペースがある最初のボックス座標を選択します。他のアイテムは使用できないスペースとして配置されます。
アイテムが現在の向きに合わない場合は、簡単にするために45度の回転を想定せずに、6つの可能な回転のいずれかで回転させます。 (すでにテスト済みの場所をスキップできるサイズになる回転。例:ボックスを180度回転すると、元の位置と同じ寸法になります。これは、すべてのボックスとアイテムが反対側の面で同じサイズであり、スキップできるためです。)
アイテムを回転して元の向きに戻していない場合は、手順3からやり直してください。
すべての回転が試行され、適合が見つからなかった場合は、現在の座標を使用できないスペースと見なします。
チェックする利用可能なスペースがない場合は、falseを返します。それ以外の場合は、ステップ3からやり直してください。
提示された制約を踏まえて、私の問題に対する最善の解決策があるかどうかを知りたいです。
これは理論上は機能するようですが、コードでは試していません。私が正しい方向に進んでいるかどうか、またはこれを実行するより良い、パフォーマンスの高い方法があるかどうかを知りたいです。
参考文献は素晴らしいでしょう。
編集:
私がやりたいことを実行するいくつかの興味深いサードパーティAPIを見つけましたが、これは切断する必要があるため、これらにアクセスすることはできません。
次に例を示します。
編集2:
解決すべき問題の実例は次のとおりです。
このアイテムを1つ以上のサイズのボックスに、可能な限り少ないボックスを使用して、可能な限り最小のボックスを使用し、空きスペースをできるだけ残して、どのように合わせるのですか?
ビンパッキングは計算上非常に困難です。問題の半分を考えてみてください。製品を箱に入れて、箱に無駄を入れないようにします。そのための最適なソリューションは、1つのトラックで出荷する必要がある製品のすべての可能なサブセットとすべての可能な3D配置を通過することを必要とします。朝食の前に6つの不可能なことをする友人がいるので、そのための最適なソリューションを紹介します。
今、あなたは無駄なくトラックのすべての箱を手に入れる必要があります。私の友人は彼の2番目の不可能なことをしてあなたに解決策を与えます。残念ながら、上で選択したボックスサイズでは、最初のタスクで別の(大きいまたは小さい)ボックスを選択した場合に減少する可能性のあるトラック内の空きスペースがあります。 1つのボックスのサイズを変更する場合、せいぜいトラックを再梱包する必要があります。最悪の場合、すべてのボックスを再梱包する必要がありますが、これは最初に発生した問題と同じくらい難しいものです。そして、最初のステージと同様に、可能な3Dアレンジをすべて試す必要があります。
SkienaのThe Algorithm Design Manual は、どの種類のアルゴリズムがどの種類の問題に適しているかを考えるのに役立つことがわかりましたが、ほとんどの場合、平凡な問題でも優れたソリューションが計算の困難に直面して爆発することを学びました。あなたが必要としているもののほとんどは bin-packing problem のクラスに当てはまり、その記事は良い出発点です。このタスクはロジスティクスの至る所に表示されるため、これに最適なアルゴリズムのいくつかは商用製品であることは注目に値します(商品を入れることができる列車の最小数はいくつですか?)。適切なヒューリスティックスによって製造業者が月に100台の列車を節約できれば、かなりの収入が得られます。
残念ながら、ヒューリスティックの最適化に関する文献は、アルゴリズムほど大きくありません。一人で行こうと思ったら、2か月目までに直角プリズムを動かすことを夢見るでしょう。私には、在庫切れの問題がありました。もう一度やり直さなければならない場合は、おそらくエキスパート(または彼らの所有権ソフトウェア)に農場を譲るでしょう。
コメントを細かく拡張してくれた@JTranaに感謝します。
投稿で言及しているヒューリスティックは興味深いようです。
最終的なソリューションを改善するために、いくつかの変更を提案します。
1つのボックスにすべてのアイテムを詰めたソリューションを考えて、2つの小さなボックスの内容を1つの大きなボックスにマージしてみてください(これは、できるだけ少数のボックスを使用する基準を改善するのに役立つはずです)。
または、新しいボックスを開始するたびに、現在のアイテムを収容できる最小のボックスを使用する代わりに、それを収容できる最大のボックスを選択し、すべてのアイテムをボックスに割り当てたら、小さな箱にボックス。
また、フィット関数では、他のボックスの位置を固定されていると見なす代わりに、ロードシーケンスを変更することを想像できます。これにより、実行時間が長くなる代わりに、より良いソリューションを見つけることができます。
新しいアルゴリズムを作成するとき、私は最近自分でパッキングアルゴリズムを実行しただけです(まだ最適化の可能性があることはわかっています)、常に最も単純なアプローチを実行します。
人間としてどうやってそれをアルゴリズムに変換してみてください:(ロボット工学)AI教師であるRolf Pfeiferから、私はまだ心に留めていますが、明らかなインテリジェンスは非常に単純なルールで作成される場合があるため、オーバーエンジニアリングの代わりに私はアンダーエンジニアリングを試みます
残りのアイテムについては、新しいベストボックスを検索してください。 ...
X.常に例外的なイベントについて考えます(特大のアイテム、奇妙なフォーム、ボックスに1つのアイテムしか含まれていない場合、ボックスなしでアイテムを送信するほうがいいのではないかなど)。しかし、決定の形でもヒューリスティックを行うことができます。木。
もちろん、あなたが得るより多くの警告があります、私はこれらのアイデアを出発点として与えるだけです。そこから可能な方法はたくさんあります。 1つの代替方法は、ボックスを小さな立方体(たとえば、5cmx5cmx5cm)に分割し、それらを占有/フリーとして追跡することです。別のアプローチは、3dテトリスなどと呼ばれます。
このアプローチでは、必ずしも組み合わせ爆発を心配する必要はありません。一方、アイテムのトレインロードについて話していると、組み合わせ爆発が発生する可能性がありますが、繰り返しになります。本当に、会社がアイテムごとにパッキングリストをチェックすると思いますか?いいえ、彼らは分割統治ソリューションにアプローチしません:標準化されたボリューム(たとえば、パレットや固定サイズのボックス)を使用して複雑さを分割します。したがって、実務のためであっても、トレーニングだけでなく、従業員の時間もお金になることを考慮に入れてください。列車はx個のパレットをロードできます。すべてのパレットには一定の体積があるため、アイテムをパレットにパックしますが、おそらくパレットは複数の順序で構成されているため、アイテムに固定ボックスを使用し、それをパレットにロードしてからロードします。電車に。
少なくともそれが私が人間としてタスクに対処する方法であり、最高のボックスを取得し、利用可能な最小のスペースに最大のアイテムを1つずつフィットさせます(そして、プレビューを少し追加します)。
私のアルゴリズムのように、結局のところ、おそらく最良の解決策はありませんが、その後さらに洗練させることができる、かなり良いヒューリスティックです。
時には、最初のステップから始めて、途中で問題を解決する方が簡単な場合があります。もちろん、エッジステップよりも一種のステップではなく、理想的には少し賢いです...場合によっては、代替策を模索して選択することを強いられることがあります。最高のものか、「後退」を実装します。
しかし、私がAIの先生から学んだように(Rolf Pfeifer、申し訳ありませんが、申し訳ありません):いくつかの非常にシンプルで少数のルールセットで明らかなインテリジェントな動作を作成できる場合があります。右側に障害物を検出し、左側に障害物がある場合は右折し、障害物がない場合、または前方に障害物がある場合は直進します。そのようなロボットが3つまたは4つある場合は、3m x 3mの正方形にたくさんのピンポンボールを配置すると、ロボットが掃除しているように見え、ピンポンボールが隅に押し出されているように見えます。障害物を避けるためにのみプログラムされています。
PD:私がこのアプローチから見つけた唯一の現実の逸脱は、メタリカ、アイアンメイデン、ブリトニースピア、ポールmcCartney、Uという名前の大きなコンサートのステージハンドとしてパートタイムで働いていたときです...国際ツアーには、アイテムごとに正確な梱包リストがあります。計算は1回行われ(人間や機械にはわからない)、その後複製されます。時々、彼らが初めて荷造りするとき、彼らはレイヤーごとの写真を作り、それをトラック内に貼り付けて、地元の乗組員が正確に知っているようにします。しかし、これは特定の梱包ニーズでもあります。1つのツアーでは、彼らは常に同じボックスとトラックで作業します。