Caso de Python: problema de ocho reinas

Descripción del problema

Hay un tablero de ajedrez de 8x8 con 8 piezas de ajedrez en él, y la fila, columna y diagonal de cada pieza de ajedrez no pueden tener otra pieza de ajedrez. De la siguiente manera, la primera imagen es una forma de cumplir las condiciones, y la segunda imagen no cumple las condiciones.
El problema de las ocho reinas es esperar encontrar todas las condiciones que cumplan con las condiciones.

Inserte la descripción de la imagen aquí
Resumen del péndulo como estructura de datos

Obviamente, la forma de cumplir las condiciones debe ser un peón en cada fila. Podemos definir una lista, el índice de la lista representa el número de fila (comenzando desde 0) y el valor representa la posición de la columna (comenzando desde 0).

Por ejemplo, puede utilizar la lista [0,1,2,3,4,5,6,7] para representar las siguientes situaciones:

O * * * * * * *
* O * * * * * *
* * O * * * * *
* * * O * * * *
* * * * O * * *
* * * * * O * *
* * * * * * O *
* * * * * * * O

Cuando necesitamos la salida, solo necesitamos restaurar la estructura:

def print_queens(result):
    print('='*10)
    for i in result:
        print("* "*i,end="")
        if(i>=0):
            print("O ",end="")
        print("* "*(len(result) - i - 1))

Cómo juzgar si una pieza de ajedrez cumple con los requisitos

Nuestra idea es colocar las piezas de ajedrez fila por fila de arriba a abajo, y comprobar si cumplen los requisitos después de no colocar una pieza.

Luego existen tres tipos de no conformidades:

  1. Ya hay una pieza directamente encima de la pieza;
  2. Ya hay una pieza en la diagonal superior izquierda de la pieza;
  3. Ya hay una pieza en la diagonal superior derecha de la pieza;
O * * * * * * *
* * O * * * * *
* * * C * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *

La situación anterior se puede representar mediante [0,2, -1, -1, -1, -1, -1, -1], donde -1 significa que la línea aún no se ha investigado y el comportamiento que queremos examinar es la segunda línea ( Empiece desde 0).

Registramos el índice de la fila a investigar como cur_index, y el valor a investigar es value.Los tres casos se pueden convertir al juicio de la lista:

  1. Ya hay una pieza justo encima de la pieza;
    el valor ya existe en la lista, por ejemplo [0,2,2, -1, -1, -1, -1, -1]
  2. Ya hay una pieza en la diagonal superior izquierda de la pieza; el
    índice se empujó previamente n lugares, y hay valor-n = cur_index-n, por ejemplo [0,2,3, -1, -1, -1, -1, -1]
  3. Ya hay una pieza en la diagonal superior derecha de la pieza; el
    índice fue previamente empujado por n lugares, y hay valor-n = cur_index + n, por ejemplo [0,2,1, -1, -1, -1, -1, -1]
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
res = []

def check(row, column):
    # 逐行向上考察
    for (index, value) in enumerate(result[:row][::-1]):
        # 这三种分别表示在正上方,右上对角线,左上对角线存在棋子
        if value in [column, column + index + 1, column - index - 1]:
            return False
    result[row] = column
    return True

Multinivel para anidación de bucles para investigar todas las situaciones

Este tipo de código se comprende mejor, pero se estima que es una locura cuando se escribe y no puede extenderse al problema de n reinas.

def enum_queens_iter():
    length = len(result)
    for r0 in range(length):
        if check(0,r0):
            result[0] = r0
            for r1 in range(length):
                if check(1,r1):
                    result[1] = r1
                    for r2 in range(length):
                        if check(2,r2):
                            result[2] = r2
                            for r3 in range(length):
                                if check(3,r3):
                                    result[3] = r3
                                    for r4 in range(length):
                                        if check(4,r4):
                                            result[4] = r4
                                            for r5 in range(length):
                                                if check(5,r5):
                                                    result[5] = r5
                                                    for r6 in range(length):
                                                        if check(6,r6):
                                                            result[6] = r6
                                                            for r7 in range(length):
                                                                if check(7,r7):
                                                                    result[7] = r7
                                                                    print_queens(result)

Convertir a forma recursiva

A partir del código anterior, podemos ver que hay muchos códigos repetidos y existe una relación estructural entre los códigos repetidos, este tipo de código generalmente se puede convertir en una forma recursiva.

En el siguiente código, solo inspeccionamos la primera línea de la pieza a inspeccionar cada vez, y luego inspeccionamos la pieza restante cuando se cumplen los requisitos.

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
result = [-1] * 8
def enum_queens(row_index):
    length = len(result)

    # 考察当前部分的第一行
    for i in range(length):
        if(check(row_index,i)):
            if row_index == length - 1:
                global total_num
                total_num+=1
                print_queens(result)
            # 考察剩余的部分
            enum_queens(row_index+1)

if __name__ == "__main__":
    enum_queens(0)

Supongo que te gusta

Origin blog.csdn.net/sinat_38682860/article/details/108711766
Recomendado
Clasificación