Exemple #1
0
def possibilities(node):
    """Compte le nombre de choix possible."""
    state = numpify_state(node.state)
    possibilities = 0
    for i, j in zip(*np.where(state == 0)):
        line = state[i]
        column = state[:,j]
        square = state[i//3*3:i//3*3+3,j//3*3:j//3*3+3]
        possibilities += len(reduce(np.setdiff1d, [np.arange(1, 10), line, column, square.flatten()]))
    return possibilities
Exemple #2
0
def remaining_blanks(node):
    """Heuristique basée sur le nombre de cases vides."""
    state = numpify_state(node.state)
    return state[state == 0].size
    blanks = 3 * 729
    for i, j in zip(*np.where(state == 0)):
        line = state[i]
        column = state[:,j]
        square = state[i//3*3:i//3*3+3,j//3*3:j//3*3+3]
        blanks -= line[line == 0].size * column[column == 0].size * square[square == 0].flatten().size
    return blanks
Exemple #3
0
def conflicts(node):
    """Heuristique qui compte le nombre de conflits dans une grille pour un
    Sudoku remplit aléatoirement."""
    state = numpify_state(node.state)
    conflicts = 0
    for i in xrange(9):
        for j in xrange(9):
            value = state[i][j]
            line = state[i]
            column = state[:,j]
            conflicts += line[line == value].size + column[column == value].size - 2
    return conflicts
Exemple #4
0
 def value(self, state):
     """
     The value of a state is determined by the sum of remaining possibilities
     for each cell in the grid.
     """
     state = numpify_state(state)
     possibilities = 729
     for i, j in zip(*np.where(state == 0)):
         line = state[i]
         column = state[:,j]
         square = state[i//3*3:i//3*3+3,j//3*3:j//3*3+3]
         possibilities -= len(reduce(np.setdiff1d, [np.arange(1, 10), line, column, square.flatten()]))
     return possibilities
Exemple #5
0
    def actions(self, state):
        """
        les actions sont déterminées en retournant les possibilitiés qui
        manquent simultanément dans une ligne, colonne et grille correspondantes
        à une case.

        La position de la case et la nouvelle valeur possible est retournée sous
        forme d'un triplet (i, j, k).
        """
        state = numpify_state(state)

        for i, j in zip(*np.where(vlen(state) > 1)):
            for k in state[i, j]:
                yield i, j, k
Exemple #6
0
def non_inferable_cells(node):
    """
    Compte le nombre de cases qui ne peuvent pas être inférées, soit les cases
    qui ont plus d'une possibilité.
    """
    state = numpify_state(node.state)
    non_inferable = 0
    for i, j in zip(*np.where(state == 0)):
        line = state[i]
        column = state[:,j]
        square = state[i//3*3:i//3*3+3,j//3*3:j//3*3+3]
        possibilities = len(reduce(np.setdiff1d, [np.arange(1, 10), line, column, square.flatten()]))
        if possibilities > 1:
            non_inferable += 1
    return non_inferable
Exemple #7
0
    def __init__(self, initial, super_branch = True):
        """Remplit la grille avec des valeurs qui respectent les carrés."""
        state = numpify_state(initial)

        # préserve les positions initiales
        self.initial_positions = list(zip(*np.where(state == 0)))

        # initialise la grille en respect des carrés
        for i, j in zip(*np.where(state == 0)):
            square = state[i//3*3:i//3*3+3,j//3*3:j//3*3+3]
            possibilities = np.setdiff1d(np.arange(1, 10), square.flatten())
            state.itemset((i, j), possibilities[0])

        self.initial = tuple(state.flatten())
        self.super_branch = super_branch
Exemple #8
0
    def goal_test(self, state):
        """
        Détermine si une configuration donnée est valide en supposant les carrés
        valides.

        Seul les lignes et les colonnes sont vérifiées.
        """
        state = numpify_state(state)
        for line in state:
            if np.bincount(line).max() > 1:
                return False
        for column in state.T:
            if np.bincount(column).max() > 1:
                return False
        return True
Exemple #9
0
    def result(self, state, action):
        """
        Calcule la configuration résultante à appliquer une action sur une
        configuration.

        Le nouvel état est une copie modifiée de l'état passé en argument.
        """
        state = numpify_state(state)

        i, j, k = action

        state.itemset((i, j), frozenset([k]))

        # normalize
        normalized_state = normalize_state(state)

        return tuple(normalized_state.flatten())
Exemple #10
0
 def value(self, state):
     """
     La valeur d'un état est déterminé par le nombre de cases
     non-conflictuelles, considérant qu'il n'y a pas de conflits sur les
     carrés.
     """
     state = numpify_state(state)
     conflicts = 0
     for i in xrange(9):
         for j in xrange(9):
             if (i, j) not in self.initial_positions:
                 value = state[i][j]
                 line = state[i]
                 column = state[:,j]
                 conflicts += line[line == value].size + column[column == value].size - 2
     # on cherche à minimiser les conflits (au plus 81 * 4 = 324)
     return -1*conflicts
Exemple #11
0
    def actions(self, state):
        """
        les actions sont déterminées en retournant les possibilitiés qui
        manquent simultanément dans une ligne, colonne et grille correspondantes
        à une case.

        La position de la case et la nouvelle valeur possible est retournée sous
        forme d'un triplet (i, j, k).
        """
        state = numpify_state(state)
        for i, j in zip(*np.where(state == 0)):
            line = state[i]
            column = state[:,j]
            square = state[i//3*3:i//3*3+3,j//3*3:j//3*3+3]
            for k in xrange(1, 10):
                # valide la nouvelle configuration et s'assurant qu'une même
                # valeur non-nulle n'apparait pas plus d'une fois dans la ligne,
                # colonne et carré correspondant
                if k not in line and k not in column and k not in square:
                    yield i, j, k