13 marzo 2025

Backtracking

Il backtracking è una tecnica algoritmica ampiamente utilizzata che esplora in modo efficiente tutte le possibili soluzioni a un problema costruendo progressivamente le soluzioni candidate ed eliminando quelle che non soddisfano i vincoli. Viene comunemente applicato in problemi di ottimizzazione combinatoria, decision-making e soddisfazione dei vincoli.

Cos’è il Backtracking?

Il backtracking è un metodo sistematico per cercare tutte le soluzioni potenziali a un problema evitando calcoli inutili. Funziona costruendo progressivamente soluzioni e abbandonando quelle parziali che si sa essere non valide, un processo noto come potatura (pruning). Questo approccio rende il backtracking significativamente più efficiente rispetto ai metodi di forza bruta che esplorano ciecamente tutte le possibilità.

Come Funziona il Backtracking?

Il backtracking segue un approccio di ricerca in profondità (DFS) e può essere suddiviso nei seguenti passaggi:

  1. Scegli: Seleziona un’opzione tra quelle disponibili.
  2. Esplora: Procedi ricorsivamente con la scelta selezionata.
  3. Annulla la scelta (Backtrack): Se la scelta porta a una soluzione non valida o insoddisfacente, annulla la scelta e prova l’alternativa successiva.

Questo processo continua fino a trovare una soluzione valida o esaurire tutte le possibilità.

Applicazioni del Backtracking

Il backtracking è utilizzato in diversi ambiti dell’informatica, in particolare nei problemi che coinvolgono permutazioni, combinazioni e vincoli. Alcune applicazioni note includono:

Risoluzione del Problema delle N Regine

Il problema delle N regine è un classico esempio di backtracking. L’obiettivo è posizionare N regine su una scacchiera N×N in modo che nessuna minacci un’altra. L’algoritmo procede come segue:

  1. Posizionare una regina nella prima riga.
  2. Passare alla riga successiva e posizionare una regina in una colonna sicura.
  3. Continuare fino a posizionare tutte le regine o fare backtrack se non si trova una posizione sicura.

Ripetere fino a trovare tutte le disposizioni valide.

Ecco un’implementazione semplice del problema delle N regine in JavaScript:

function solveNQueens(n) {
  function isSafe(board, row, col) {
    for (let i = 0; i < row; i++) {
      if (board[i] === col || Math.abs(board[i] - col) === row - i) {
        return false;
      }
    }
    return true;
  }

  function backtrack(board, row) {
    if (row === n) {
      solutions.push([...board]);
      return;
    }
    for (let col = 0; col < n; col++) {
      if (isSafe(board, row, col)) {
        board[row] = col;
        backtrack(board, row + 1);
        board[row] = -1;
      }
    }
  }

  let solutions = [];
  backtrack(new Array(n).fill(-1), 0);
  return solutions;
}

console.log(solveNQueens(4)); // Example output for a 4x4 board

Ottimizzazioni nel Backtracking

Sebbene il backtracking sia più efficiente rispetto alla forza bruta, ulteriori ottimizzazioni possono migliorarne le prestazioni: