web-dev-qa-db-ja.com

Python長方形のパッキング

複数の長方形を大きな長方形(境界ボックス)にパックするプロジェクトに取り組んでいます。四角形は、互いに、または境界ボックスの境界とオーバーラップできません。長方形は回転して、状態空間をn! * 2^n n個の長方形の問題。

これらの問題を「解決する」Pythonプログラムを記述しようとしています。たとえば、長方形のセットと境界ボックスを指定すると、すべての可能な解決策が見つかるはずです。深さ優先を使用しています検索アルゴリズムは今ですが、プログラムを高速化するための多くの最適化が欠けているように感じます。私のアルゴリズムは次のように機能します。

  1. 大きいバウンディングボックスの列の高さを表す値をすべて0に初期化したリストがあります。
  2. 境界ボックスで最初の空のスポットを探します。これは、最小値の列で表されます。
  3. 現在の四角形がその場所に収まる場合は、右側の列の高さを四角形の高さだけ増やすことによって、四角形を「配置」します。
  4. 四角形がフィットしなくなり、他の可能なソリューションに戻ることができなくなるまで、2および3を繰り返します。

(疑似)コードでは、次のようになります。

def solve(rectangles):

    # Solution found
    if rectangles is empty:
        add_to_solutions()
        return

    position = find_first_empty_spot()
    for rectangle in rectangles:
        for r in [rectangle, rectangle.rotated()]:
            if rectangle fits at given position:
                place_rectangle_in_bounding_box(r)
                remove r from rectangles
                solve(remaining_rectangles)
                remove_rectangle_from_bounding_box(r)

アルゴリズムの基本は正しいですか、それともいくつかの(明らかな)改善が欠けていますか?最大20の長方形のサイズの問題を解決することは素晴らしいことですが、私の現在のアルゴリズムはそれらを解決するのに時間がかかりすぎます。

そして、私は問題に対する「すべての」可能な解決策を見つけようとしています。「a」の解決策を見つけた直後に止めることはできません。そのため、文献にある多くの発見的方法は当てはまりません。

6
Koen

あなたが尋ねている問題は、非常に多くの用途があるよく知られた問題です。たとえば、家具製造における材料の無駄を最小限に抑えるタスク:特定の部分(長方形のリスト)は、所定の合板のボードから切り取られる必要がありますサイズ(境界矩形)。あなたがすでにすべての可能な解決策を見つけることを理解しているように見えるように、 組み合わせのNP困難な問題 です。

したがって、業界では通常、すべての可能な解決策を見つけることを主張するのではなく、代わりに 近似アルゴリズム を使用します。 。したがって、現在私があなたの質問にできる最善の答えは、 このBPPの例をここに示すことです オープンソース Python OpenOptパッケージ からのソルバーの使用を示します。

私の理解では、可能な解決策をすべて列挙したいというあなたの願いは、20四角程度の適度な数であっても、許容可能な時間内に満たすことは不可能です。これが真実でない場合、私も知り、学びたいと思っています。

3
pefu