L'analyse de problème la plus concise et le résumé de routine des huit reines de l'histoire

Adresse github du projet: bitcarmanlee easy-algorithm-interview-and-practice
accueille tout le monde pour jouer, laisser un message, apprendre et progresser ensemble

1. Quel est le problème des huit reines

Le problème des huit reines est un problème basé sur les échecs: comment placer huit reines sur un échiquier 8 × 8 afin qu'aucune reine ne puisse capturer directement les autres reines? Pour atteindre cet objectif, deux reines ne peuvent pas être sur la même ligne horizontale, verticale ou diagonale. Le problème des huit reines peut être généralisé au problème plus général de placement des n-reines: la taille de l'échiquier devient n × n, et le nombre de reines devient également n. Le problème peut être résolu si et seulement si n = 1 ou n ≥ 4. (La description du problème provient de la référence 1)

Insérez la description de l'image ici

Le prince des mathématiques Gauss a passé d'innombrables travaux acharnés cette année-là et a finalement calculé qu'il y avait 76 solutions au problème des huit reines.Nous pouvons maintenant calculer facilement les vraies solutions au problème des huit reines grâce à des simulations informatiques. On peut imaginer la complexité et la difficulté des calculs qui peuvent faire trébucher Gauss.

2. Analyse de la solution

Gauss dérive 76 solutions des huit reines, ce qui est déjà très puissant. Cela ne peut pas blâmer Gauss, mais la complexité de calcul des huit reines est en effet trop élevée.
L'idée générale du problème reste une solution violente
1. Commencez par énumérer toutes les méthodes de placement possibles des reines.
2. Vérifiez si la méthode de placement répond aux exigences.

Le processus de mise en œuvre spécifique est le suivant:
mettez d'abord la première reine dans la première ligne et la première colonne, puis placez la deuxième reine dans la deuxième ligne et la première colonne, pour déterminer si l'arrangement répond aux exigences. Evidemment cela ne fonctionnera pas, il y aura deux reines dans la même colonne. Mettez la deuxième reine dans la deuxième ligne et la deuxième colonne. Cela ne fonctionnera pas. Les deux reines seront sur une ligne diagonale. Mettez la deuxième reine dans la deuxième ligne et la troisième colonne afin que les conditions actuelles soient remplies.
Il y a déjà deux reines qui remplissent les conditions, puis mettez la troisième, ou commencez par la première colonne de la troisième rangée, et mettez la deuxième colonne si la condition n'est pas remplie, la troisième colonne ... jusqu'à la huitième reine peut également être placé Dans une position non conflictuelle, trouvez une solution qui répond aux exigences à ce stade.
Ensuite, nous commençons à revenir en arrière et à placer la première reine dans la première ligne et la deuxième colonne, et cette dernière continuera à boucler de la manière ci-dessus jusqu'à ce que le retour en arrière soit terminé et que toutes les solutions qui remplissent les conditions soient trouvées.

La référence 2 a une image, qui décrit le processus ci-dessus plus en détail, et l'a publiée pour votre référence. La figure suivante décrit le processus de retour en arrière des 4 reines, et le principe est le même que celui des 8 reines.
Insérez la description de l'image ici

3. Mise en œuvre du code

Une fois l'analyse du principe ci-dessus terminée, examinons l'implémentation du code.

public class NQueueV2 {

    public static int N = 4;
    public static int[][] boards = new int[N][N];

    public static int result = 0;

    public static void putQueQue(int k) {
        if (k == N) {
            result++;
            for(int row=0; row<N; row++) {
                for(int col=0; col<N; col++) {
                    System.out.print(boards[row][col] + " ");
                }
                System.out.println();
            }
            System.out.println();
        } else {
            for(int i=0; i<N; i++) {
                if (check(k, i)) {
                    boards[k][i] = 1;
                    putQueQue(k+1);
                    boards[k][i] = 0;
                }
            }
        }
    }

    public static boolean check(int row, int column) {
        for(int i=0; i<row; i++) {
            if (boards[i][column] == 1) {
                return false;
            }
        }

        for(int m=row-1, n=column-1; m>=0 && n >= 0; m--, n--) {
            if (boards[m][n] == 1) {
                return false;
            }
        }

        for(int m=row-1, n=column+1; m>=0 && n<N; m--, n++) {
            if (boards[m][n] == 1) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        putQueQue(0);
        System.out.println("result is: " + result);
    }
}

Résultat de sortie de code:

0 1 0 0 
0 0 0 1 
1 0 0 0 
0 0 1 0 

0 0 1 0 
1 0 0 0 
0 0 0 1 
0 1 0 0 

result is: 2

Le code ci-dessus, afin de faciliter la sortie du résultat final, simule 4 reines, et 8 reines n'ont besoin que de changer N en 8.

Un tableau bidimensionnel de plateau, qui simule un échiquier, et l'état initial est 0, ce qui signifie qu'aucune reine n'est placée à cette position. Si la position est définie sur 1, cela signifie qu'il y a une reine dans la position.

k représente le nombre de reines placées. Si k == N, cela signifie que toutes les N reines ont été placées, et une solution valide est obtenue à ce moment.

            for(int row=0; row<N; row++) {
                for(int col=0; col<N; col++) {
                    System.out.print(boards[row][col] + " ");
                }
                System.out.println();
            }

Cette partie du code affiche l'état d'une solution valide. La position 1 dans le tableau indique que la reine est placée à cette position.

Sinon une partie du code, i représente la i-ème colonne, et la méthode check (k, i) représente s'il est légal de placer la reine à la position (k, i)

        for(int i=0; i<row; i++) {
            if (boards[i][column] == 1) {
                return false;
            }
        }

Cette partie du code signifie que deux reines ne peuvent pas être placées dans la même colonne.

        for(int m=row-1, n=column-1; m>=0 && n >= 0; m--, n--) {
            if (boards[m][n] == 1) {
                return false;
            }
        }

Cette partie du code signifie que la barre oblique gauche de la reine ne peut pas avoir de reine.

        for(int m=row-1, n=column+1; m>=0 && n<N; m--, n++) {
            if (boards[m][n] == 1) {
                return false;
            }
        }

Cette partie du code signifie que la partie droite de la barre oblique de la reine ne peut pas avoir de reine.

Si la reine peut être placée à cette position, réglez la position sur l'échiquier sur 1, puis placez la reine putQueQue (k + 1) sur la ligne suivante. Dans le même temps, lors du retour en arrière, la position doit être définie sur 0.

4. Résumé de routine

Donc, le problème apparemment compliqué des huit reines, en regardant le diagramme, puis en regardant l'analyse du code, ne semble-t-il pas si difficile?
L'essence est l'utilisation d'algorithmes classiques de retour arrière, similaires aux permutations et aux combinaisons que nous avons mentionnées précédemment. Après avoir compris l'ensemble du processus, la difficulté du retour en arrière est encore moindre que celle de la permutation et de la combinaison!
Une explication détaillée de l'algorithme de permutation et de combinaison le plus complet de l'histoire et un résumé des routines sont présentés dans un article

les références

1.https: //zh.wikipedia.org/wiki/%E5%85%AB%E7%9A%87%E5%90%8E%E9%97%AE%E9%A2%98
2.https: // juejin.cn/post/6844903798926753805

Je suppose que tu aimes

Origine blog.csdn.net/bitcarmanlee/article/details/114548541
conseillé
Classement