Sto utilizzando simulated annealing per risolvere un problema di pianificazione delle risorse NP-complete. Per ogni candidato che ordina i compiti, computo diversi costi (o valori energetici) diversi. Alcuni esempi sono (anche se le specifiche sono probabilmente irrilevante per la questione):Come progettare la funzione di probabilità di accettazione per la ricottura simulata con costi distinti multipli?
global_finish_time
: Il numero totale di giorni in cui le campate di pianificazione.split_cost
: il numero di giorni entro i quali ogni attività viene ritardata a causa di interruzioni da parte di altre attività (questo è inteso a scoraggiare l'interruzione di un'attività dopo l'avvio).deadline_cost
: la somma del numero quadrato di giorni entro cui ogni scadenza mancata è scaduta.
La funzione di probabilità di accettazione tradizionali assomiglia a questo (in Python):
def acceptance_probability(old_cost, new_cost, temperature):
if new_cost < old_cost:
return 1.0
else:
return math.exp((old_cost - new_cost)/temperature)
Finora ho combinato i miei primi due costi in un unico semplicemente aggiungendoli, in modo che possa alimentare il risultato in acceptance_probability
. Ma quello che vorrei davvero è che per deadline_cost
abbia sempre la precedenza su global_finish_time
e che per global_finish_time
abbia la precedenza su split_cost
.
Quindi la mia domanda su Stack Overflow è: come posso progettare una funzione di probabilità di accettazione che tenga conto di più energie ma considera sempre la prima energia più importante della seconda energia, e così via? In altre parole, vorrei passare in old_cost
e new_cost
come tuple di diversi costi e restituire un valore ragionevole.
Edit: Dopo alcuni giorni di sperimentazione con le soluzioni proposte ho concluso che l'unico modo che funziona abbastanza bene per me è il suggerimento di Mike Dunlavey, anche se questo crea molte altre difficoltà con componenti di costo che hanno diverse unità . Sono praticamente costretto a confrontare le mele con le arance.
Quindi, ho messo un po 'di sforzo per "normalizzare" i valori. Innanzitutto, deadline_cost
è una somma di quadrati, quindi cresce in modo esponenziale mentre gli altri componenti crescono in modo lineare. Per risolvere questo problema, utilizzo la radice quadrata per ottenere un tasso di crescita simile. In secondo luogo, ho sviluppato una funzione che calcola una combinazione lineare dei costi, ma regola automaticamente i coefficienti in base alla componente di costo più elevata vista finora.
Ad esempio, se la tupla dei costi più elevati è (A, B, C) e il vettore del costo di input è (x, y, z), la combinazione lineare è BCx + Cy + z. In questo modo, non importa quanto alto z lo ottiene non sarà mai più importante di un valore x di 1.
Questo crea "frastagliature" nella funzione di costo quando vengono scoperti nuovi costi massimi. Ad esempio, se C sale, allora BCx e Cy saranno entrambi più alti per un dato input (x, y, z) e quindi anche le differenze tra i costi. Una maggiore differenza di costo significa che la probabilità di accettazione diminuirà, come se la temperatura fosse improvvisamente abbassata di un ulteriore passo. In pratica però questo non è un problema perché i costi massimi vengono aggiornati solo poche volte all'inizio e non cambiano in seguito. Credo che si possa persino teoricamente dimostrare che convergere in un risultato corretto poiché sappiamo che il costo convergerà verso un valore inferiore.
Una cosa che mi ha ancora un po 'confuso è cosa succede quando i costi massimi sono 1.0 e inferiori, diciamo 0.5. Con un vettore massimo di (0,5, 0,5, 0,5) questo darebbe la combinazione lineare 0,5 * 0,5 * x + 0,5 * y + z, vale a dire.l'ordine di precedenza è improvvisamente invertito. Suppongo che il modo migliore per affrontarlo sia utilizzare il vettore massimo per ridimensionare tutti i valori su intervalli dati, in modo che i coefficienti possano essere sempre gli stessi (ad esempio, 100x + 10y + z). Ma non l'ho ancora provato.
Sarei interessato a sapere se questo è un problema industriale o accademico. Cordiali saluti –
Non è accademico. Sto usando questo come alternativa a MS Project. L'obiettivo principale del programma è rendere più semplice la risposta alla domanda "quando la tua squadra può aggiungere la funzionalità X al nostro software?" – flodin
So che questa domanda è vecchia di anni ma per chiunque altro incappi in questa pagina tramite Google ... in logica fuzzy la somma ponderata è l'equivalente di OR logico, quindi stai dicendo in modo efficace "se condizione A * O * condizione B ecc. ". Quello che vuoi veramente è A * AND * B * AND * C, e per farlo usi la moltiplicazione. Ci sono alcuni avvertimenti (ad esempio, i tuoi pesi ora devono essere dei poteri) ma è molto meglio del casino che stai provando nel caso speciale. Wiki "Weighted sum model" e "Weighted product model" per maggiori dettagli. –