Quello che vorrei fare è dividere un gruppo di (n) elementi in gruppi di uguali dimensioni (gruppi di dimensioni m, e per semplicità supponiamo che non ci sono avanzi, cioè n è divisibile di m). Facendo questo più volte, vorrei assicurarmi che nessun paio di elementi sia nello stesso gruppo insieme due volte.Come generare (in modo efficiente) set disgiunti mentre le coppie di elementi usanti una sola volta?
per rendere questo un po 'più concreto, per la costruzione di gruppi di due dei sei elementi A..F
, una volta potrebbe partizionare il set per cinque volte in modi diversi:
(A, B)
,(C, D)
,(E, F)
(A, C)
,(B, E)
,(D, F)
(A, D)
,(B, F)
,(C, E)
(A, E)
,(B, D)
,(C, F)
(A, F)
,(B, C)
,(D, E)
Lo stesso gruppo di elementi può essere partizionato sola volta in gruppi di tre colpo coppie sovrapposte:
(A, B, C)
,(D, E, F)
(As @DavidHam gli uomini sottolineano di seguito, ci sono diversi modi di rendere la partizione in questo esempio. Tuttavia, dopo aver creato la partizione una volta, non c'è mai un'altra suddivisione, che mantiene separate tutte le coppie di oggetti. C'è un modo: - Va bene la mia applicazione non necessita di generare tutte possibilmente modi di partizionamento del set a livello globale, una soluzione incontro i vincoli faranno)
La mia domanda, ora, è questo di farlo in modo efficiente? Ci sono trucchi per accelerare la generazione di questi set?
Quindi, finora, ho considerato questo come un problema exact cover e lo risolvo con un backtracking algorithm (una variante di DLX). Questo funziona molto bene per le coppie, ma man mano che i gruppi diventano più grandi il numero di possibilità che l'algoritmo deve considerare esplode, e l'elaborazione diventa molto ingombrante.
Quello che sto cercando sono i trucchi per velocizzare le cose. Tutte le idee sono i benvenuti, in particolare (ma non solo):
- Ottimizzazioni e euristica per ridurre il numero di possibilità che devono essere considerati prima di risolvere (ad esempio, è chiaro dagli esempi sopra che la prima divisione può essere fatta semplicemente arbitrariamente, e la prima serie di ciascuna partizione [la prima colonna sopra] può essere generata automaticamente).
- Esistono varianti di backtracking che possono far fronte a enormi quantità di candidati? (non avendo bisogno di generare tutte le possibilità in anticipo)
- Altri algoritmi , approcci o concetti matematici che dovrei considerare?
Qualsiasi idea e suggerimento è molto gradita. Grazie mille per aver considerato questo!
Aggiornamento
Ok, quindi questo è stato un po ', ma ho speso molto più tempo su questo e voleva tornare a voi. @ david-eisenstat mi ha messo sulla strada giusta dandomi il termine di ricerca corretto (grazie mille!) - Da allora ho letto abbastanza sul problema del golfista sociale.
Una delle migliori risorse che ho trovato, che mi piacerebbe condividere qui, è il lavoro di Markus Triska, che discute diversi approcci (e poi continua a presentare un algoritmo molto carino) nella sua tesi. Questo è altamente raccomandato se qualcuno si imbatte in un problema simile!
Re * Lo stesso insieme di oggetti può essere partizionato solo una volta in gruppi di tre, senza sovrapposizione di coppie *: Cosa c'è di sbagliato con '((ABD), (CEF))' e '((ABE) (CDF)) ', e almeno altri sei? La domanda come indicato non specifica il motivo per cui hai escluso quelle combinazioni. –
@DavidHammen la coppia A B sembra essere nello stesso gruppo in entrambe le partizioni. Nella domanda dell'OP affermava che * nessun paio di articoli è nello stesso gruppo insieme due volte * –
Grazie mille, voi due! @DavidHammen: Hai perfettamente ragione nel dire che avrei potuto usare uno dei tuoi esempi invece di quello che ho dato. Lo chiarirò nella domanda. – mezzopiano