2013-03-09 9 views
7

Ho un grafico particolarmente grande, che rende quasi impossibile attraversare l'utilizzo della ricorsione a causa dell'eccessiva quantità di memoria che utilizza.Implementazione di uno stack esplicito in una prima ricerca di profondità

Qui di seguito è la mia funzione in profondità, utilizzando la ricorsione:

public function find_all_paths($start, $path) 
{ 
    $path[] = $start; 
    if (count($path)==25) /* Only want a path of maximum 25 vertices*/ { 
     $this->stacks[] = $path; 
     return $path; 

    } 
    $paths = array(); 

    for($i = 0; $i < count($this->graph[$start])-1; $i++) { 
     if (!in_array($this->graph[$start][$i], $path)) { 
    $paths[] = $this->find_all_paths($this->graph[$start][$i], $path); 

     } 
    } 


    return $paths; 
} 

vorrei riscrivere questa funzione in modo che non è ricorsiva. Presumo che dovrò fare una coda di qualche tipo e inserire i valori usando array_shift() ma in quale parte della funzione, e come posso assicurarmi che i vertici in coda siano preservati (per inserire il percorso finale su $this->stacks)?

+0

DFS non utilizza exp. quantità di memoria. Utilizza solo memoria lineare per lo stack. – nhahtdh

+1

Nota che tutta la ricorsione può essere sostituita da iterazione che è una verità generale. La domanda è, se questo fa risparmiare memoria (come menzionato @nhahtdh). Se la dimensione massima dello stack o la profondità non sono limitati, non vedo alcun vantaggio – hek2mgl

+0

@nhahtdh Non ha detto che richiede spazio esponenziale, ha detto che richiede * spazio eccessivo *. Che è vero - a seconda di come appare il tuo grafico, DFS prende lo spazio lineare nel numero di * vertici *, che può (su grafici interamente ragionevoli) essere troppo grande per lo stack di chiamate integrato, ma abbastanza piccolo da adattarsi una struttura dati allocata all'heap. – delnan

risposta

1

Non ci vuole spazio esponenziale, il numero di percorsi in un albero è pari al numero di foglie, ogni foglia ha solo 1 percorso dalla radice ..

Ecco un DFS semplice ricerca di un binario arbitrario albero:

// DFS: Parent-Left-Right 
public function dfs_search ($head, $key) 
{ 
    var $stack = array($head); 
    var $solution = array(); 

    while (count($stack) > 0) 
    { 
     $node = array_pop($stack); 

     if ($node.val == $key) 
     { 
      $solution[] = $node; 
     } 

     if ($node.left != null) 
     { 
      array_push($stack, $node.left); 
     } 

     if ($node.right != null) 
     { 
      array_push($stack, $node.right); 
     } 
    } 

    return $solution; 
} 

Quello che è necessario trovare tutti i percorsi in un albero è semplicemente branch & forcella, il che significa ogni volta che si ramo, ogni ramo prende una copia del percorso attuale .. ecco un ramo ricorsivo 1-line & fork ho scritto:

// Branch & Fork 
public function dfs_branchFork ($node, $path) 
{ 
    return array($path) 
     +($node.right!=null?dfs_branchFork($node.right, $path+array($node)):null) 
     +($node.left!=null?dfs_branchFork($node.left, $path+array($node)):null); 
} 
+0

@PseudoOne controlla la mia soluzione alla tua domanda –

Problemi correlati