Questo è un lavoro di ottimizzazione, e piuttosto complesso se stai cercando la soluzione ottimale the . Fortunatamente credo che sia uno di quei casi in cui andrà bene.
La prima cosa da fare è stabilire un criterio di qualità matematico, ovvero una formula che, data una permutazione della lista, restituirà un singolo numero che descrive quanto sia buona o cattiva tale permutazione.
Un semplice suggerimento di formula, ogni criterio che vorresti prendere in considerazione dovrebbe avere un peso, dare un peso elevato a criteri importanti e un peso basso ai criteri in cui molte canzoni condividono la stessa proprietà, in modo che quelle non dominare:
For each song on the list
For each other song on the list
For each criteria
If the two songs share that criteria
Add to the quality value: square root( [criteria weight]/[distance between the two songs] )
Più basso è il valore di questa procedura, migliore è la permutazione della lista.
Esecuzione della permutazione
Ora potresti prendere questa formula per math.stackexchange e farti dire quanto sia follemente difficile e possibilmente impossibile trovare la soluzione ottimale per qualsiasi cosa tranne un numero insignificante di canzoni, o potresti semplicemente lanciarle cicli di clock e ottieni una buona soluzione.
Ci sono molti modi per farlo, eccone uno:
Start with a random permutation of the list.
Several million times do the following:
Select two entries at random
For each of those two entries calculate their contribution to the quality value
Swap the positions of the two entries
Calculate the contribution to the quality value of the two entries at their new position
If the sum of the calculations in the new positions is greater than the sum in the old positions
Swap back
Questo è un algoritmo un po 'dispendioso, ma è facile da implementare e può gestire tutti i criteri che desideri.
Ottimizzazioni
È possibile applicare diversi ritocchi e ottimizzazioni, eccone alcuni:
Nel calcolo del valore di qualità, non preoccuparti di controllare una canzone contro ogni altra canzone della lista, invece basta controllarla contro le circa 100 canzoni più vicine. Per valori comuni questa ottimizzazione della velocità non ha praticamente alcuna influenza sulla qualità del risultato.
Per un valore raro di una determinata proprietà può essere più efficiente tenere traccia delle istanze esistenti di quel valore piuttosto che cercarle.
Se ritieni che sia importante che i valori con poche istanze siano distanziati in modo uniforme, piuttosto che molto distanti, è probabilmente necessario aumentare il peso per quei valori specifici, ma non per altri valori di quel criterio.
Una funzione pseudo-casuale che seleziona tutte le coppie possibili dalla lista in una distribuzione equa può avere un rendimento leggermente migliore per ogni prelievo rispetto a una scelta casuale normale.