Introduction
So today, I will be talking about the backtracking algorithm, one of my favorite algorithms. Maybe it's just because of the name "backtracking" or just the reason being it avoids all the collusion or problems. A peaceful environment, I would say. So let's hop into the problem.
What is backtracking?
In backtracking algorithms, we try to build a solution one step at a time. If, at some step, it becomes clear that the current path that we are on cannot lead to a solution, we go back to the previous step (backtrack) and choose a different path. Basically, once we exhaust all our options at a certain step we go back. The classic example of backtracking is the Eight Queen Problem.
What is N Queen's Problem?
The idea is to place queens one by one in different columns, starting from the leftmost column. When we place a queen in a column, we check for clashes with already placed queens. In the current column, if we find a row for which there is no clash, we mark this row and column as part of the solution. If we do not find such a row due to clashes then we backtrack and return false.
- Start in the leftmost column.
- If all queens are placed, return true.
- Try all rows in the current column.
- Do the following for every tried row.
- If the queen can be placed safely in this row, then mark this [row, column] as part of the solution and recursively check if placing the queen here leads to a solution.
- If placing the queen in [row, column] leads to a solution, then return true.
- If placing queen doesn't lead to a solution then mark this [row, column] (Backtrack) and go to step (a) to try other rows.
- If all rows have been tried and nothing worked, return false to trigger backtracking.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Backtracking
{
class Program
{
static int N;
static void printBoard(int[,] board)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
Console.Write(board[i, j] + " ");
}
Console.Write("\n");
}
}
static bool toPlaceOrNotToPlace(int[,] board, int row, int col)
{
int i, j;
for (i = 0; i < col; i++)
{
if (board[row, i] == 1)
return false;
}
for (i = row, j = col; i >= 0 && j >= 0; i--, j--)
{
if (board[i, j] == 1)
return false;
}
for (i = row, j = col; j >= 0 && i < N; i++, j--)
{
if (board[i, j] == 1)
return false;
}
return true;
}
static bool theBoardSolver(int[,] board, int col)
{
if (col >= N)
return true;
for (int i = 0; i < N; i++)
{
if (toPlaceOrNotToPlace(board, i, col))
{
board[i, col] = 1;
if (theBoardSolver(board, col + 1))
return true;
// Backtracking is important in this one.
board[i, col] = 0;
}
}
return false;
}
static void Main(string[] args)
{
Console.WriteLine("State the value of N in this program!");
N = Convert.ToInt32(Console.ReadLine());
int[,] board = new int[N, N];
if (!theBoardSolver(board, 0))
{
Console.WriteLine("Solution not found.");
}
printBoard(board);
Console.ReadLine();
}
}
}