Table of Contents
Local Branching
Il Local Branching è una tecnica metaeuristica alternativa all’Hard Fixing, in cui non impostiamo direttamente le variabili, ma, tramite un vincolo, scegliamo solo quante.
Nell’hard fixing, data la soluzione euristica , dobbiamo decidere quante variabili fissare a 1 e quali. L’intuizione del local branching è quello di scegliere solo quante:
Il vincolo dà gradi di libertà al modello. Con do uno spazio di ricerca come nel 2-OPT, ma già dal 3-OPT abbiamo un algoritmo , mentre nel Local Branching possiamo esplorare una neighborhood anche di efficientemente.
L’approccio non è specifico per il TSP, ma vale in generale.
Quando è piccolo (ordine di 20), il MIP solver è più veloce nonostante il vincolo aggiuntivo. Con CPLEX moderno ci si spinge a .
Discussione
Sto dando al modello di CPLEX un taglio molto deep, che possibilmente potrebbe tagliare il convex hull ottimo (che per il tsp non conosciamo).
Nonostante ciò, il gap che otteniamo è molto più basso. Il gap senza il vincolo sarebbe gigantesco da colmare con il solo Branch&Cut.
Se metto k troppo grande, il gap risulterà troppo grande. Invece se k è troppo piccolo, CPLEX risolverà subito il modello e sarà inutile.
Da notare che il vincolo proposto vale in questo caso SOLO per il TSP
- Per evitare di riesplorare parti già visitate:
aggiungere vincolo
in realtà aggiungere questi vincoli non danno migliorie. - Suggerisce ad ogni iterazione di aumentare il e ricordarsi di cancellare il vincolo precedente. Come?
ConCPXgetnumrowsprima di mettere il vincolo saprò la posizione dove metterà il vincolo, una volta che voglio rimuoverlo esiste una funzione che rimuove il vincolo in quella posizione.
La formulazione generale del vincolo di Local branching è indipendente dal significato di 0 e 1:
Nel TSP il numero di 1 nella soluzione è sempre (ogni nodo ha grado 2), quindi i flip da e da sono sempre in numero uguale. Si sta calcolando la stessa cosa due volte: si può quindi usare la versione asimmetrica, eliminando uno dei due termini oppure portando il bound a .
Struttura
La struttura iterativa: si parte da un iniziale; se non si trova una soluzione migliorante entro il timelimit, si aggiorna e si ripete.
Due motivi per cui non funziona:
- troppo grande -> troppi gradi di libertà, gap enorme
- si parte da una molto scarsa
In CPLEX, prima di aggiungere il vincolo, salvare la posizione corrente con CPXgetnumrows. Quando si vuole rimuovere il vincolo precedente, usare quella posizione. Sempre cancellare il vincolo precedente prima di aggiungere uno nuovo con aggiornato.
Estensione
Dal Paper “Learning to Search”, rete neurale per determinare il .
Invece di usare una NN, si calcola il minimo tale che la soluzione ottima rimanga raggiungibile:
Si usa poi come punto di partenza. Procedura:
build_model- Rilassare MIP -> LP
CPXlpopt->CPXgetsolper- Calcolare
- Reimpostare le variabili a binarie
'B'e tornare a MIP conCPXchprobtype(..., CPX_MIP) - Applicare Local branching con il calcolato
per convertire da MIP a LP
- settare le variabili (colonne) a intere [^1] (non più binarie), quindi per ogni variabile devo chiamare
CPXsetctype(env,lp, j, 'C') - CPXchproblem(…, CPX_RELAX_LP)
- CPXchprep(…, CPX_MIP)
- alla fine reimpostare tutte le variabili a ‘B’
[^1] : cytpe = ‘C’
See also
- Other Metaheuristics — Simulated Annealing e Genetico affrontano lo stesso problema di diversificazione/intensificazione con approcci diversi