Ejemplo de aplicación de algoritmo recursivo: algoritmo de ocho reinas

Problema de las ocho reinas

Caso clásico de algoritmo de retroceso

Caso típico de algoritmo de retroceso. El problema fue planteado por el jugador de ajedrez Max Bethel en 1848: Coloca ocho reinas en un tablero de ajedrez de 8X8 para que no puedan atacarse entre sí, es decir: dos reinas cualesquiera no pueden salir en la misma línea. En la misma columna o en el misma línea diagonal, pregunte cuántas formas hay.

Análisis de pensamiento

  1. La primera reina se coloca en la primera fila y en la primera columna.
  2. Coloque la segunda reina en la primera columna de la segunda fila y luego juzgue si es 0 K. Si no está bien, continúe colocándola en la segunda y tercera columnas, ponga todas las columnas en orden y encuentre una adecuada
  3. Continuar hasta la tercera reina, y aún desvanecerse la primera y segunda columnas ... Hasta que la octava reina pueda colocarse en una posición no conflictiva, se considera que se ha encontrado una solución correcta.
  4. Cuando se obtiene una solución correcta, cuando la pila retrocede a la pila anterior, comenzará a retroceder, es decir, la primera reina, ponga todas las soluciones correctas en la primera columna, todas obtienen
  5. Luego regrese y continúe con la primera, coloque la segunda reina en la segunda columna, y luego continúe con los pasos 1, 2 y 3.

** Explicación: ** En teoría, se debería crear una matriz bidimensional para representar el tablero de ajedrez, pero de hecho, se puede utilizar una matriz unidimensional para resolver el problema mediante algoritmos. Arr [8] = {0,4 , 7,5,2, 6, 1, 3) representa una solución positiva

El subíndice arr correspondiente indica el número de filas, es decir, el número de reinas, arr [i] = val, val indica la i + 1ª reina, colocada en la columna val + 1ª de la fila i + 1ª

La eficiencia puede ser relativamente baja, y también existen algoritmos para optimizarla posteriormente, como algoritmos codiciosos, etc., que se mencionarán en las siguientes notas

Código

package com.wang.Recursion;
/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/20 19:45
 * @Description TODO
 * @pojectname 八皇后问题
 */
public class Queue8 {
    
    
    //定义一个max表示共有多少个皇后
    int max = 8;
    //定义数组array,保存皇后放置的位置,比如arr[8]={0,4,7,5,2,6, 1,3}
    int[] array = new int[max];
    static int count = 0;
    public static void main(String[] args) {
    
    
        //测试
        Queue8 queue8 = new Queue8();
        queue8.check(0);
        System.out.println("一共有"+count+"次解法");
    }
    //编写一个方法,放置第n个皇后
    //特别注意:check是每一层递归时,进入到check都有for循环,因此会有回溯
    private void check(int n){
    
    
        //如果n = max,皇后放完了,
        if (n == max){
    
    
            print();
            return;
        }
        //没有放完的话,依次放入皇后,判断是否冲突
        for (int i = 0; i < max ; i++) {
    
    
            //先把当前的皇后n,放到改行的第一列
            array[n] = i;
            //判断当放置了第n个皇后到i列时,是否冲突
            if (judge(n)) {
    
    
                //不冲突,接着放n+1个皇后,即开始递归
                check(n+1);
            }
            //如果冲突,就继续执行array[n] = i;这个时候i已经++了,就是放到了下一列
        }
    }

    /**
     //查看当我们放置第n个皇后时,就去检测该皇后是否和前面已经摆好的皇后冲突
     * @param n 表示第n个皇后
     * @return
     */
    private boolean judge(int n){
    
    
        for (int i = 0; i <n ; i++) {
    
    
            //array[i] == array[n]表示第n个皇后是否和前面i个皇后是否在同一列
            //Math.abs(n-i) == Math.abs(array[n] - array[i]表示第n个皇后是否和第i个皇后在同一斜线
            if (array[i] == array[n] ||Math.abs(n-i) == Math.abs(array[n] - array[i] )){
    
    
                return false;
            }
        }
        return true;
    }

    //将皇后拜访的位置打印出来
    private void print(){
    
    
        count++;
        for (int i = 0; i <array.length ; i++) {
    
    
            System.out.print(array[i]+"");
        }
        System.out.println();
    }
}

Supongo que te gusta

Origin blog.csdn.net/qq_22155255/article/details/111462168
Recomendado
Clasificación