Imballaggio rettangolo Python

5

Sto lavorando a un progetto che consiste nel riempire più rettangoli in un rettangolo più grande (il riquadro di delimitazione). I rettangoli non possono sovrapporsi l'uno con l'altro o con i limiti del riquadro di delimitazione. I rettangoli possono ruotare, aumentando lo spazio degli stati in n! * 2^n per problemi di n rettangoli.

Sto provando a scrivere un programma Python che "risolve" questi problemi, ad esempio dovrebbe trovare tutte le possibili soluzioni dato un insieme di rettangoli e un rettangolo di selezione. In questo momento sto utilizzando un algoritmo di ricerca approfondito, ma mi sento come se mi mancassero molte ottimizzazioni per accelerare il mio programma. Il mio algoritmo funziona come segue:

  1. Ho una lista con valori che rappresentano l'altezza delle colonne nel riquadro di delimitazione più grande, inizializzato su tutti gli 0.
  2. Cerco il primo punto vuoto nel riquadro di delimitazione, che è rappresentato dalla colonna con il valore più piccolo.
  3. Se il rettangolo corrente si adatta a quel punto, I 'posiziona' il rettangolo aumentando l'altezza delle colonne a destra in base all'altezza del rettangolo.
  4. Ripeti 2 e 3 fino a quando non è più possibile inserire altri rettangoli e torna ad altre possibili soluzioni.

Nel codice (pseudo-) sembra che questo:

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)

Le basi del mio algoritmo sono corrette o mi mancano alcuni (ovvi) miglioramenti? Sarebbe bello risolvere problemi di dimensioni fino a 20 rettangoli, ma il mio algoritmo attuale richiederebbe troppo tempo per risolverli.

E: sto cercando di trovare "tutte" le possibili soluzioni al problema, non posso semplicemente fermarmi dopo aver trovato una "soluzione", quindi molte euristiche trovate in letteratura non sono applicabili.

    
posta Koen 04.05.2015 - 11:20
fonte

1 risposta

2

Il problema che ti stai ponendo è un problema ben noto che ha una pletora di applicazioni: ad esempio il compito di ridurre al minimo lo spreco di materiale nella produzione di mobili: alcuni pezzi (il tuo elenco di rettangoli) devono essere ritagliati da tavole di compensato in una determinata dimensione (il rettangolo di delimitazione). Come sembri aver già capito, trovare tutte le possibili soluzioni è un problema combinatorio NP-difficile .

Pertanto nel settore di solito non insistiamo nel trovare tutte le possibili soluzioni, ma invece utilizziamo un algoritmo di approssimazione che potrebbe ovviamente non sempre forniamo la migliore soluzione possibile. Quindi attualmente la risposta migliore che posso dare alla tua domanda è quella di indirizzarti a questo BPP esempio qui che illustra l'uso di un risolutore dall'open source Pacchetto Python OpenOpt .

Da quanto ho capito, il tuo desiderio di elencare tutte le possibili soluzioni è impossibile da realizzare in un tempo accettabile anche per un numero moderato di dire 20 rettangoli o giù di lì. Se questo non è vero, sono anche ansioso di conoscere e imparare.

    
risposta data 15.05.2015 - 14:22
fonte

Leggi altre domande sui tag