3

I'm working on a DFS based solution to the N-queens problem.

I store the board state as an int[N] array representing the vertical placements of queens in each column (eg. placement of the queens diagonally down a 6x6 board would be state = { 0, 1, 2, 3, 4, 5 }), where -1 represents "no queen in this column".

My current algorithm for counting the queen attacks in a given state configuration has complexity of O(n^2):

function count_attacks(state)

    attack_count = 0

    for each column index c1
      if state[c1] == -1 continue

      for each column index c2 further along than c1
        if state[c2] == -1 continue

        // Lined up horizontally?
        if state[c1] == state[c2] attack_count++    

        // Lined up diagonally?
        else if (c2 - c1) == abs(state[c2] - state[c1]) attack_count++   

       // No need to check lined up vertically as impossible with this state representation

    return attack_count;

The O(N^2) kills performance when solving for say N=500+.

Is it possible to do better than O(N^2) for counting attacks?

Brendan Hill
  • 3,406
  • 4
  • 32
  • 61

1 Answers1

3

Define arrays

rows, columns, left_diagonals, right_diagonals

which count respectively the number of queens in the i-th row, column, left diagonal (all x and y such that x-y=c for some c), right diagonal (all x and y such that x+y=c for some c). The algorithm would then be:

Intialize rows, columns, left_diagonals, right_diagonals with zero values
attacks = 0
for queen in queens
    attacks += rows[queen.row];
    attacks += columns[queen.column];
    attacks += left_diagonals[queen.left_diagonal];
    attacks += right_diagonals[queen.right_diagonal];
    rows[queen.row]++;
    columns[queen.column]++;
    left_diagonals[queen.left_diagonal]++;
    right_diagonals[queen.right_diagonal]++;

However, for solving the N queen problem you don't need to check the number of attacks. You just need to check if an attack exists.

Also, if you are looking for a single solution of the problem there is a very efficient algorithm.

sve
  • 4,336
  • 1
  • 19
  • 30