La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Scrivere un algoritmo non deterministico di complessita` polinomiale che risolva il problema del commesso viaggiatore. Vengono proposte due soluzioni,

Presentazioni simili


Presentazione sul tema: "Scrivere un algoritmo non deterministico di complessita` polinomiale che risolva il problema del commesso viaggiatore. Vengono proposte due soluzioni,"— Transcript della presentazione:

1 Scrivere un algoritmo non deterministico di complessita` polinomiale che risolva il problema del commesso viaggiatore. Vengono proposte due soluzioni, entrambe riconducibili allo schema generale. Nella soluzione I l’insieme delle scelte varia, nel senso che ad ogni città visitata dal commesso viaggiatore tale città viene eliminata dall’insieme delle scelte che potranno essere fatte successivamente. Nella soluzione II, invece, l’insieme delle scelte resta inalterato, ma ad ogni scelta si dovrà verificare che la città non sia già stata visitata. Le città siano numerate da 1 a n, e 1 sia la città di partenza. Chiamiamo D la tabella della distanze (cioè il grafo memorizzato come matrice di adiacenza), k il costo da non superare, entrambi forniti in input, e C il vettore che memorizza il percorso, se esiste; la variabile costo e` usata per ricordare il costo del cammino.

2 ND1_commesso_viaggiatore (D,C, k) C[1]  1 costo  0 I_S  {2, …, n} for i  2 to n do C[i]  choice (I_S) I_S  I_S - {C[i]} costo  costo + D C[i-1],C[i] if costo > k then failure costo  costo + D C[n],C[1] if costo > k then failure else success I soluzione NON_deterministica (…) … for i  1 to n do I  ins. delle scelte per A[i] if I =  then failure A[i]  choice (I) If A[1],…,A[i] “non puo` diventare una soluzione” then failure else if “e` una soluzione” then success failure (success)

3 ND2_commesso_viaggiatore (D,C, k) C[1]  1 costo  0 for i  2 to n do C[i]  choice ({2, …, n}) for j  2 to (i - 1) do if C[i] = C[j] then failure costo  costo + D C[i-1],C[i] if costo > k then failure costo  costo + D C[n],C[1] if costo > k then failure else success II soluzione NON_deterministica … for i  1 to n do I  ins. delle scelte per A[i] if I =  then failure A[i]  choice (I) If A[1],…,A[i] “non puo` diventare una soluzione” then failure else if “e` una soluzione” then success failure (success)

4 Equivalente algoritmo deterministico per enumerazione I soluzione comm_viaggiatore1 (D, C, k) C[1]  1 costo  0 I_S  if En_C_V (2, I_S, costo) then costo  costo + D C[n],C[1] if costo  k then return true return false

5 En1_C_V (i, I_S, costo) if i  n then for j  1 to |I_S| do C[i]  I_S[j] costo  costo + D C[i-1],C[i] I_S  I_S - {C[i]} if costo  k then if En_C_V (i+1, I_S, costo) then return true return false else return true Enum (i,...) if i  n then I  ins. scelte per A[i] if I =  then return false for j  1 to |I| do A[i]  I[j] if A[1],…,A[i] “puo` diventare una soluzione” then if “e` una soluzione” then return true if Enum (i+1,...) then return true return false else return false (true)

6 Attenzione! Ci sono due errori dovuti a due caratteristiche che distinguono questo problema da quelli visti a lezione (Domino_limitato e Cricca) I side-effect negativi ai quali si deve rimediare quando si effettua back-tracking in Domino e Cricca erano rimediati dalle assegnazioni successive costo  costo - D C[i-1],C[i] I_S  I_S  {C[i]} In questo caso invece, se il for deve essere eseguito per un altro valore di j, il costo e l’insieme delle scelte devono essere ripristinati al valore che avevano prima dell’ultima “strada” tentata, cioè:

7 if i  n then for j  1 to |I_S| do C[i]  I_S[j] costo  costo + D C[i-1],C[i] I_S  I_S - {C[i]} if costo  k then if En1_C_V (i+1, I_S, costo) then return true Otteniamo così la seguente versione costo  costo - D C[i-1],C[i] I_S  I_S  {C[i]} return false else return true En1_C_V (i, I_S, costo)

8 Per Domino e Cricca una volta trovata una soluzione è inutile continuare a tentare strade alternative sull’albero delle scelte. Per il Commesso Viaggiatore, al contrario, quando aggiungendo il costo dell’ultimo tratto di chiusura del percorso si scopre che il costo complessivo supera k, non si ha la sicurezza che la soluzione non esista. Bisogna esplorare le scelte alternative, se ne restano. Come rimediare? Basta spostare il controllo relativo all’ultimo tratto di percorso 1 - nei punti in cui si rientra con successo, oppure 2 - sulle foglie dell’albero delle scelte, cioè all’ultimo richiamo ricorsivo, quando i > n.

9 if i  n then for j  1 to |I_S| do C[i]  I_S[j] costo  costo + D C[i-1],C[i] I_S  I_S - {C[i]} if costo  k then if En_C_V (i+1, I_S, costo) and costo + D C[i-1],C[i]  k then return true costo  costo - D C[i-1],C[i] I_S  I_S  {C[i]} return false else return true En11_C_V (i, I_S, costo) 1 - nei punti in cui si rientra con successo

10 if i  n then for j  1 to |I_S| do C[i]  I_S[j] costo  costo + D C[i-1],C[i] I_S  I_S - {C[i]} if costo  k then if En_C_V (i+1, I_S, costo) then return true costo  costo - D C[i-1],C[i] I_S  I_S  {C[i]} return false else if costo + D C[n],C[1]  k then return true else return false En12_C_V (i, I_S, costo) 2 - all’ultimo richiamo ricorsivo

11 if i  n then for j  1 to |I_S| do C[i]  I_S[j] costo  costo + D C[i-1],C[i] I_S  I_S - {C[i]} if costo  k then if En11_C_V (i+1, I_S, costo) then return true costo  costo - D C[i-1],C[i] I_S  I_S  {C[i]} return false else if costo + D C[n],C[1]  k then return true else return false En12_C_V (i, I_S, costo) In definitiva, poichè il controllo nel programma principale è diventato inutile, si ottiene: comm_viaggiatore1 (D, C, k) C[1]  1 costo  0 I_S  if En_C_V (2, I_S, costo) then return true return false

12 comm_viaggiatore2 (D,C, k) C[1]  1 costo  0 if En2_C_V (2, costo) then return true return false II soluzione

13 En2_C_V (i, costo) if i  n then for j  2 to n do C[i]  j t  2 while t  i-1 and C[i]  C[t] do t  t + 1 if t = i then costo  costo + D C[i-1],C[i] if costo  k then if En2_C_V (i+1, costo) then return true costo  costo - D C[i-1],C[i] Enum (i,...) if i  n then I  ins. scelte per A[i] if I =  then return false for j  1 to |I| do A[i]  I[j] if A[1],…,A[i] “ puo` diventare una soluzione” then if “e` una soluzione” then return true else if Enum (i+1,...) then return true return false else return false (true) return false else if costo + D C[n],C[1]  k then return true else return false

14 En2_C_V (i, costo) if i  n then for j  2 to n do C[i]  j t  2 while t  i-1 and C[i]  C[t] do t  t + 1 if t = i then costo  costo + D C[i-1],C[i] if costo  k then if En2_C_V (i+1, costo) then return true costo  costo - D C[i-1],C[i] return false else if costo + D C[n],C[1]  k then return true else return false comm_viaggiatore2 (D,C, k) C[1]  1 costo  0 if En2_C_V (2, costo) then return true return false


Scaricare ppt "Scrivere un algoritmo non deterministico di complessita` polinomiale che risolva il problema del commesso viaggiatore. Vengono proposte due soluzioni,"

Presentazioni simili


Annunci Google