示例#1
0
        /// <summary>
        /// Algorithme permettant de verifier avec un temps d'avance si des valeurs legales ne pourront jamais etre assigne a une variable
        /// </summary>
        /// <param name="cspBase">Les contraintes actuelles sur le sudoku</param>
        /// <param name="assignement">L'attribution actuelle des variables</param>
        /// <param name="lastAssignedVariable">La derniere variable attribue</param>
        /// <returns>Les contraintes possiblement avec des valeurs legales en moins</returns>
        public static SudokuCSP ACThree(SudokuCSP cspBase, SudokuSolver.SudokuAssignment assignement, SudokuSolver.SudokuVariable lastAssignedVariable)
        {
            // Le fait d'effectuer une copie permet de ne pas avoir a s'inquieter de reset les changements qui on ete effectue
            // dans l'algorithme si le chemin n'est pas retenue
            // Cela amene cependant une complexite suplementaire dans l'algorithme
            SudokuCSP newCsp = new SudokuCSP(cspBase);

            // On modifie a jour le domaine de la derniere variable assigne
            // Cela est fait dans cette fonction car cela permet de ne pas avoir a se souvenir du domaine modifie
            // si jamais l'assignement de cette variable ne permet pas de resoudre le sudoku
            newCsp.m_variablesDomain[lastAssignedVariable.X, lastAssignedVariable.Y].Clear();
            newCsp.m_variablesDomain[lastAssignedVariable.X, lastAssignedVariable.Y].Add(assignement.Grid[lastAssignedVariable.X, lastAssignedVariable.Y]);
            foreach (SudokuSolver.SudokuVariable neighbor in newCsp.m_variableRemainingNeighbor[lastAssignedVariable.X, lastAssignedVariable.Y])
            {
                newCsp.m_variableRemainingNeighbor[neighbor.X, neighbor.Y].Remove(lastAssignedVariable);
            }

            Queue <Tuple <SudokuSolver.SudokuVariable, SudokuSolver.SudokuVariable> > arcs = new Queue <Tuple <SudokuSolver.SudokuVariable, SudokuSolver.SudokuVariable> >();

            // On fait d'abord un tour sur les arcs entre toute les variables restantes et leur voisin
            foreach (SudokuSolver.SudokuVariable remainingVariable in assignement.RemainingVariable)
            {
                // Ici du fait que l'on sache dans quel variable on va modifier les domaines, on peut se permettre de ne pas rajouter ses voisins
                // a chaque fois qu'on lui enleve un domaine
                bool remove = false;
                foreach (SudokuSolver.SudokuVariable neighbor in newCsp.m_variablesNeighbors[remainingVariable.X, remainingVariable.Y])
                {
                    remove |= RemoveInconsistentValue(newCsp, remainingVariable, neighbor);
                }
                if (remove)
                {
                    foreach (SudokuSolver.SudokuVariable remainingNeighbor in newCsp.m_variableRemainingNeighbor[remainingVariable.X, remainingVariable.Y])
                    {
                        arcs.Enqueue(new Tuple <SudokuSolver.SudokuVariable, SudokuSolver.SudokuVariable>(remainingNeighbor, remainingVariable));
                    }
                }
            }

            // On effectue ensuite les operations necessaire sur la queue jusqu'a ce que celle-ci soit vide
            while (arcs.Count != 0)
            {
                Tuple <SudokuSolver.SudokuVariable, SudokuSolver.SudokuVariable> arc = arcs.Dequeue();
                if (RemoveInconsistentValue(newCsp, arc.Item1, arc.Item2))
                {
                    foreach (SudokuSolver.SudokuVariable remainingNeighbor in newCsp.m_variableRemainingNeighbor[arc.Item1.X, arc.Item1.Y])
                    {
                        arcs.Enqueue(new Tuple <SudokuSolver.SudokuVariable, SudokuSolver.SudokuVariable>(remainingNeighbor, arc.Item1));
                    }
                }
            }

            return(newCsp);
        }
示例#2
0
        /// <summary>
        /// Constructeur de copie
        /// </summary>
        /// <param name="otherCSP">Le CSP a copie</param>
        public SudokuCSP(SudokuCSP otherCSP)
        {
            m_size = otherCSP.m_size;
            m_variablesNeighbors        = otherCSP.m_variablesNeighbors;
            m_variablesDomain           = new List <int> [m_size, m_size];
            m_variableRemainingNeighbor = new List <SudokuSolver.SudokuVariable> [m_size, m_size];

            for (int x = 0; x < m_size; x++)
            {
                for (int y = 0; y < m_size; y++)
                {
                    m_variablesDomain[x, y]           = new List <int>(otherCSP.m_variablesDomain[x, y]);
                    m_variableRemainingNeighbor[x, y] = new List <SudokuSolver.SudokuVariable>(otherCSP.m_variableRemainingNeighbor[x, y]);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Enleve les valeurs inconsistante des valeurs legales d'une variable
        /// </summary>
        /// <param name="csp">Les contraintes actuelle sur le sudoku</param>
        /// <param name="variableToCheck">La variables dont on verifie les valeurs legales</param>
        /// <param name="variableNeighbor">Un voisin de la variable</param>
        /// <returns></returns>
        static bool RemoveInconsistentValue(SudokuCSP csp, SudokuSolver.SudokuVariable variableToCheck, SudokuSolver.SudokuVariable variableNeighbor)
        {
            bool       removed      = false;
            List <int> domainsNode1 = new List <int>(csp.m_variablesDomain[variableToCheck.X, variableToCheck.Y]);
            List <int> domaineNode2 = csp.m_variablesDomain[variableNeighbor.X, variableNeighbor.Y];

            foreach (int x in domainsNode1)
            {
                // Si le domaine de la variable voisine ne contient qu'une seule valeur c'est qu'elle a soit ete assigne
                // soit c'est la seule variable que l'on peut lui assigne.
                // Dans tous les cas on ne pourra pas donner cette valeur a la variable courante
                if (domaineNode2.Contains(x) && domaineNode2.Count == 1)
                {
                    csp.m_variablesDomain[variableToCheck.X, variableToCheck.Y].Remove(x);
                    removed = true;
                    break;
                }
            }
            return(removed);
        }