def main():
    print("\n\n\nEnter the maze number that you want to solve.")
    mazeNumber = int(input("[1]. maze1.txt \t 2. maze2.txt \t 3. maze3.txt\n"))

    print("\n\nEnter algorithm number you would like to use.")
    algoPref = int(
        input(
            "[1]. Djikstra's \n 2. Breadth First Searh \n 3. Depth First Search \n 4. Backtracking\n"
        ))

    print("\n\nDo you want to get the output in color?")
    color = input("[Y]es\t\tNo\n")

    maze, start, end = mazes(mazeNumber)

    if algoPref == 4:
        path = backtracking(maze, start)
    elif algoPref == 3:
        path = dfs(maze, start)
    elif algoPref == 2:
        path = bfs(maze, start)
    else:
        path = djikstras(maze, start)

    # Printing the maze with the solution for the respective path finding algorithm
    currNode = end
    while currNode != (0, 1):
        nextNode = path[currNode]
        connectTwoCells(maze, currNode, nextNode)
        currNode = nextNode
    if color == "Y" or color == "y" or color.capitalize() == "Yes":
        printMazeInColor(maze)
    else:
        printMaze(maze)
Ejemplo n.º 2
0
def main():
    """
    Shows how backtracking is applied
    Renders the unsolved and solution of the given sudoku puzzle
    """

    # Create a blank Sudoku board
    board = create_empty_board()

    # Sample Board config
    board[0] = [0, 0, 0, 2, 6, 0, 7, 0, 1]
    board[1] = [6, 8, 0, 0, 7, 0, 0, 9, 0]
    board[2] = [1, 9, 0, 0, 0, 4, 5, 0, 0]
    board[3] = [8, 2, 0, 1, 0, 0, 0, 4, 0]
    board[4] = [0, 0, 4, 6, 0, 2, 9, 0, 0]
    board[5] = [0, 5, 0, 0, 0, 3, 0, 2, 8]
    board[6] = [0, 0, 9, 3, 0, 0, 0, 7, 4]
    board[7] = [0, 4, 0, 0, 5, 0, 0, 3, 6]
    board[8] = [7, 0, 3, 0, 1, 8, 0, 0, 0]

    solved_board, steps = backtracking(deepcopy(board))

    # Show unsolved puzzle
    cv2.imshow("Unsolved", draw_puzzle(board))
    cv2.waitKey(0)

    if steps:
        # Show solved puzzle
        cv2.imshow(f"Solved in {steps} steps", draw_puzzle(solved_board))
        cv2.waitKey(0)
    else:
        print("Invalid puzzle")

    # Close all windows
    cv2.destroyAllWindows()
 def solve(self, d_i_list):
     for d_i in d_i_list:
         print 'DoF', d_i, self.hv_counts[d_i], self.dof[d_i]
     dim = self.dim
     candidates = self.candidates
     cand_counts = [None, None]
     prev_cand_counts = [None, None]
     size = len([x for x in self.dof if x <= 500])
     while True:
         print 'Size =', size
         for d_i in d_i_list[:size]:
             self.d_i = d_i
             this_dim = dim[d_i[0]]
             that_dim = dim[1 - d_i[0]]
             this_idx = d_i[1]
             self.candidates[d_i] = []
             for candidate in backtracking(range(this_dim), Choices, self.box_assignable):
                 if candidate not in self.candidates[d_i]:
                     self.candidates[d_i].append(candidate)
             print 'D%d %2d %d/%d' % (d_i[0], d_i[1], len(self.candidates[d_i]), self.dof[d_i])
         for d in (0, 1):
             cand_counts[d] = [len(self.candidates[(d, idx)]) for idx in xrange(dim[1-d]) if (d, idx) in self.candidates]
         print cand_counts[0]
         print cand_counts[1]
         if cand_counts[0] == prev_cand_counts[0] and cand_counts[1] == prev_cand_counts[1]:
             print 'Candidate counts remain the same. Increasing size by', 4
             size += 4
         for d in (0, 1):
             prev_cand_counts[d] = cand_counts[d]
         if len(cand_counts[0]) == dim[0] and len(set(cand_counts[0])) == 1 and cand_counts[0][0] == 1:
             print '** Found unique solution'
             break
     for y in xrange(dim[1]):
         print ''.join([candidates[(0, y)][0][x] for x in xrange(dim[0])])
Ejemplo n.º 4
0
    def test_findUnassignedLocation(self):
        tempPuzzle = np.array([[7, 5, 6, 1, 3, 2, 8, 9, 4],[8, 9, 2, 6, 7, 4, 5, 3, 1],[4, 3, 1, 8, 5, 9, 6, 2, 7],[5, 4, 3, 9, 6, 8, 1, 7, 2],[2, 8, 9, 3, 0, 7, 4, 5, 6],[1, 6, 7, 4, 2, 5, 3, 8, 9],[3, 7, 4, 5, 9, 6, 2, 1, 8],[9, 1, 8, 2, 4, 3, 7, 6, 5],[6, 2, 5, 7, 8, 1, 9, 4, 3]])
        position = [0,0]

        b = backtracking.backtracking(tempPuzzle)
        b.findUnassignedLocation(tempPuzzle, position)

        self.assertEqual(position, [4,4], "Puzzle finds position wrong")
Ejemplo n.º 5
0
def test_not_fun_puzzles(not_fun_puzzles):
    # Unpack
    puzzles, solutions = not_fun_puzzles

    for puzzle, solution in zip(puzzles, solutions):
        solved, step = backtracking(puzzle)

        assert (solved == solution).all()
        assert step != 0
Ejemplo n.º 6
0
def test_difficult_puzzles(difficult_puzzles):
    # Unpack
    puzzles, solutions = difficult_puzzles

    for puzzle, solution in zip(puzzles, solutions):
        solved, step = backtracking(puzzle)

        assert (solved == solution).all()
        assert step != 0
Ejemplo n.º 7
0
def test_intermediate_puzzles(intermediate_puzzles):
    # Unpack
    puzzles, solutions = intermediate_puzzles

    for puzzle, solution in zip(puzzles, solutions):
        solved, step = backtracking(puzzle)

        assert (solved == solution).all()
        assert step != 0
Ejemplo n.º 8
0
def run():
    path = input(
        "Which method do you want to use? \nBrute force (1), Dynamic (2), Best First Branch Bound (3), or Backtracking (4)?\nOr press q to quit  : "
    )

    if path == '1':
        time1 = datetime.datetime.now()
        print(bruteforce.bruteforce(W, items[2], items[1], len(items[0])))
        time2 = datetime.datetime.now()
        tdelta = time2 - time1
        print("Brute force: Time taken: %s ms" %
              int(tdelta.total_seconds() * 1000))
        print("\n")
        run()

    elif path == '2':
        time1 = datetime.datetime.now()
        print(dynamic.dynamic(W, items[2], items[1], len(items[0])))
        time2 = datetime.datetime.now()
        tdelta = time2 - time1
        print("Dynamic: Time taken: %s ms" %
              int(tdelta.total_seconds() * 1000))
        print("\n")
        run()

    elif path == '3':
        time1 = datetime.datetime.now()
        print(
            firstBranchBound.firstBranchBound(W, items[2], items[1],
                                              len(items[0])))
        time2 = datetime.datetime.now()
        tdelta = time2 - time1
        print("Best First Branch Bound: Time taken: %s ms" %
              int(tdelta.total_seconds() * 1000))
        print("\n")
        run()

    elif path == '4':
        time1 = datetime.datetime.now()
        print(backtracking.backtracking(W, items[2], items[1], len(items[0])))
        time2 = datetime.datetime.now()
        tdelta = time2 - time1
        print("Backtracking: Time taken: %s ms" %
              int(tdelta.total_seconds() * 1000))
        print("\n")
        run()

    elif path == 'q':
        sys.exit("See ya!")

    else:
        print("Error: no valid option chosen. Please try again.")
        print("\n")
        run()
Ejemplo n.º 9
0
def GradientDescent(f, d_f, x0, epson=0.0001):
    from backtracking import backtracking
    x = [x0]

    while True:
        # determine d_x
        d_x = -d_f(x[-1])
        if d_x**2 <= epson:
            break
        t = backtracking(f, d_f, x[-1], d_x)
        x.append(x[-1] + t * d_x)
    #     print "%3.3f,%.3f,%.3f" % (d_x,t,x[-1])
    # print "Final x: ",x[-1]
    return x
Ejemplo n.º 10
0
def NewtonMethod(f, d_f, dd_f, x0, epson=0.0001):
    from backtracking import backtracking
    x = [x0]

    while True:
        df = d_f(x[-1])
        ddf = dd_f(x[-1])
        if (df**2 / ddf) / 2 <= epson:
            break
        d_x = -df / ddf
        t = backtracking(f, d_f, x[-1], d_x)
        x.append(x[-1] + t * d_x)
    #     print "%3.3f,%.3f,%.3f" % (d_x,t,x[-1])
    # print "Final x: %.3f" % (x[-1])
    return x
Ejemplo n.º 11
0
def gradientdescent(f, df, x0, e, alpha, beta):
    x_vals = []
    x = x0
    k = 0  #number of iteration
    while 1:
        #print k, x, f(x)
        # store each x, f(x) into separate list
        x_vals.append(x)

        dx = -df(x)
        t = backtracking(f, df, x, dx, alpha, beta)
        x = x + t * dx
        if (abs(df(x)) <= e):
            return x_vals, k
        k = k + 1
Ejemplo n.º 12
0
def run():
	path = input("Which method do you want to use? \nBrute force (1), Dynamic (2), Best First Branch Bound (3), or Backtracking (4)?\nOr press q to quit  : ")
	
	if path == '1':
		time1 = datetime.datetime.now()
		print( bruteforce.bruteforce(W, items[2], items[1], len(items[0])) )
		time2 = datetime.datetime.now()
		tdelta = time2 - time1
		print("Brute force: Time taken: %s ms" % int(tdelta.total_seconds()*1000) )
		print("\n")
		run()
		
	elif path == '2':
		time1 = datetime.datetime.now()
		print( dynamic.dynamic(W, items[2], items[1], len(items[0])) )
		time2 = datetime.datetime.now()
		tdelta = time2 - time1
		print("Dynamic: Time taken: %s ms" % int(tdelta.total_seconds()*1000) )
		print("\n")
		run()
	
	elif path == '3':
		time1 = datetime.datetime.now()
		print( firstBranchBound.firstBranchBound(W, items[2], items[1], len(items[0])) )
		time2 = datetime.datetime.now()
		tdelta = time2 - time1
		print("Best First Branch Bound: Time taken: %s ms" % int(tdelta.total_seconds()*1000) )
		print("\n")
		run()
	
	elif path == '4':
		time1 = datetime.datetime.now()
		print( backtracking.backtracking(W, items[2], items[1], len(items[0])) )
		time2 = datetime.datetime.now()
		tdelta = time2 - time1
		print("Backtracking: Time taken: %s ms" % int(tdelta.total_seconds()*1000) )
		print("\n")
		run()
		
	elif path == 'q':
		sys.exit("See ya!")
		
	else:
		print("Error: no valid option chosen. Please try again.")
		print("\n")
		run()
Ejemplo n.º 13
0
 def test_usedInBox(self):
     b = backtracking.backtracking(puzzle)
     self.assertTrue(b.usedInBox(puzzle, 3, 3, 7), "not finding box duplicates")
Ejemplo n.º 14
0
def test_invalid_puzzles(invalid_puzzles):
    for puzzle in invalid_puzzles:
        solved, step = backtracking(puzzle)

        assert (solved == puzzle).all()
        assert step == 0
Ejemplo n.º 15
0
    def test_usedInRow(self):

        b = backtracking.backtracking(puzzle)
        self.assertTrue(b.usedInRow(puzzle, 6, 3), "not finding row duplicates")
Ejemplo n.º 16
0
 def test_usedInCol(self):
     b = backtracking.backtracking(puzzle)
     self.assertTrue(b.usedInCol(puzzle, 2, 1), "not finding column duplicates")
Ejemplo n.º 17
0
def main(img_path):
    sudoku_solver('0000.png')
    board = digit_recognizer()
    backtracking(board)
Ejemplo n.º 18
0
from classes import Board
from backtracking import backtracking


#https://dlbeer.co.nz/articles/sudoku.html
def board_loader(board):
    with open(board) as f:
        board = csv.reader(f)
        board = [i for i in board]
    return board


if __name__ == "__main__":
    board = sys.argv[1]

    board = board_loader(board)

    board = Board(board)

    sol = backtracking(board, 0)

    if sol:
        total = sol[0]
        moves = sol[1:]

        for i in moves:
            board.board[i[0]][i[1]] = i[2]
        print("success")
    else:
        print("fail")
Ejemplo n.º 19
0
def minimize_f(x0, f, grad_f, bounds = None, method = 'projected_gradient'):
    """Solution of convex optimization problem, possibly with constraints.

    Inputs:
        x0:     Starting point
        f:      Objective function
        grad_f: Gradient of f
        bounds: Upper and lower bounds of the optimization problem. If
                specified, it must be of the form [(lower_b, upper_b)] and its
                length must be the same as the dimension of the problem
        method: Method used for solving the optimization problem

    Outputs:
        x:      Solution of the optimization problem
        f_x:    Value of the function at x
        grad_x: Gradient at x
        it:     Number of iterations needed
    """

    x           = x0.copy()
    fun_obj     = lambda x: (f(x), grad_f(x))
    f_x, grad_x = fun_obj(x)
    c1          = 1e-1
    ls_interp   = 1
    ls_multi    = 1
    convergence = False
    precision   = 1e-5
    it          = 0
    it_max      = 5000
    if bounds == None:
        l_bounds = -np.inf * np.ones(x.shape)
        u_bounds = np.inf * np.ones(x.shape)
    else:
        l_bounds = np.array([l for (l,u) in bounds])
        u_bounds = np.array([u for (l,u) in bounds])

    while not convergence:
        it += 1

        d   = -grad_x.copy()
        gtd = np.inner(d, grad_x)
        t   = 1

        t, x_new, f_new, g_new, _ = backtracking(x, t, d, f_x, grad_x, f_x, \
                gtd, c1, ls_interp = ls_interp, ls_multi = ls_multi, \
                fun_obj = fun_obj)

        x   = x_new.copy()
        x   = np.maximum(x, l_bounds)
        x   = np.minimum(x, u_bounds)
        if (x != x_new).any():
            f_new = f(x)
            g_new = grad_f(x)

        convergence = np.inner(f_new - f_x, f_new - f_x) < precision ** 2 \
                and it < it_max

        f_x     = f_new.copy()
        grad_x  = g_new.copy()

    return (x, f_x, grad_x, it)
    for i in range(0, len(inputArray)):
        for j in range(0, len(inputArray[i])):
            if (type(inputArray[i][j]) == int):
                if (inputArray[i][j] > n):
                    raise error_incorrect_input
            else:
                if (inputArray[i][j] != '_'):
                    raise error_incorrect_input

    checkInput(inputArray, nmkArray)
    print("Which would you like to implement: ")
    print("\t1. Backtracking + MRV heuristic")
    print("\t2. Backtracking + MRV + Forward Checking")
    print("\t3. Backtracking + MRV + Constraint Propagation")
    num = input("")

    temp = "None"
    if (num == "2"):
        temp = "FC"
    elif (num == "3"):
        temp = "CP"

    backtracking.backtracking(inputArray, nmkArray, temp)

except error_incorrect_input:
    print("\nIncorrect input, please try again!\n")
except FileNotFoundError:
    print("\nThis file does not exist, please try again!\n")

# testInput2.txt
# testInput.txt
Ejemplo n.º 21
0
def main():
    """
    Loops through all unsolved sudoku puzzle images, and perform all operations from grid extraction, cell extraction,
    digit classification to backtracking to find the solution of the puzzle

    Once a solution is found, renders the answers on the unsolved sudoku image
    """
    # Load trained model
    model = tf.keras.models.load_model('digits_classifier/models/model.h5')

    image_directory = "images/unsolved"
    for file_name in os.listdir(image_directory):
        # Load image
        image = cv2.imread(filename=os.path.join(image_directory, file_name),
                           flags=cv2.IMREAD_COLOR)

        # Check if image is too big
        # If so, Standardise image size to avoid error in cell image manipulation
        # Cells must fit in 28x28 for the model, big images will exceed this threshold with aspect ratio resize
        if image.shape[1] > 700:
            image = imutils.resize(image, width=700)

        # Extract grid
        grid_coordinates = get_grid_dimensions(image)

        # Check if grid is found
        if grid_coordinates is not None:
            # Crop grid with transformation
            grid = transform_grid(image, grid_coordinates)

            # Image preprocessing, reduce noise such as numbers/dots, cover all numbers
            thresh = reduce_noise(grid)

            # Contour detection again, this time we are extracting the grid
            cnts, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE,
                                               cv2.CHAIN_APPROX_SIMPLE)

            # Filter out non square contours
            cnts = filter_non_square_contours(cnts)

            # Convert contours into data to work with
            # Do a check if grid is fully extracted, no missing, no duplicates etc
            if len(cnts) == 81:
                # Sort grid into nested list format same as sudoku
                grid_contours = sort_grid_contours(cnts)

                # Create a blank Sudoku board
                board = create_empty_board()

                # Run digit classifier
                for row_index, row in enumerate(grid_contours):
                    for box_index, box in enumerate(row):

                        # Extract cell ROI from contour
                        x, y, width, height = cv2.boundingRect(box)
                        roi = grid[y:y + height, x:x + width]

                        # Convert to greyscale
                        roi = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)

                        # Image thresholding & invert image
                        digit_inv = cv2.adaptiveThreshold(
                            roi, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                            cv2.THRESH_BINARY_INV, 27, 11)

                        # Remove surrounding noise
                        digit = sudoku_cells_reduce_noise(digit_inv)

                        # Digit present
                        if digit is not None:
                            # Reshape to fit model input
                            digit = digit.reshape((1, 28, 28, 1))

                            # Make prediction
                            board[row_index][box_index] = np.argmax(
                                model.predict(digit), axis=-1)[0] + 1

                # Perform backtracking to solve detected puzzle
                solved_board, steps = backtracking(copy.deepcopy(board))

                # Check if puzzle is valid
                if steps:
                    # Solved
                    # Draw answers on the sudoku image
                    for row_index, row in enumerate(board):
                        for box_index, box in enumerate(row):
                            # Filter for BLANK_STATES
                            if box == BLANK_STATE:
                                x, y, width, height = cv2.boundingRect(
                                    grid_contours[row_index][box_index])

                                # Calculate font size
                                for num in np.arange(1.0, 10.0, 0.1):
                                    text_size = cv2.getTextSize(
                                        str(solved_board[row_index]
                                            [box_index]),
                                        fontFace=cv2.FONT_HERSHEY_DUPLEX,
                                        fontScale=num,
                                        thickness=2)

                                    font_size = num
                                    if text_size[0][
                                            0] > width // 2 or text_size[0][
                                                1] > height // 2:
                                        break

                                # Fill in answers in sudoku image
                                cv2.putText(
                                    image,
                                    str(solved_board[row_index][box_index]),
                                    (x + grid_coordinates[0][0] +
                                     (width * 1 // 4),
                                     y + grid_coordinates[0][1] +
                                     (height * 3 // 4)),
                                    cv2.FONT_HERSHEY_SIMPLEX, font_size,
                                    (0, 255, 0), 2)

                    # Fill in information at bottom left
                    cv2.putText(image, f"Solved in {steps} steps",
                                (0, image.shape[0]), cv2.FONT_HERSHEY_SIMPLEX,
                                font_size, (0, 255, 0), 2)

                    # Save answers in solved directory
                    cv2.imwrite(
                        f"images/solved/{os.path.splitext(file_name)[0]}.png",
                        image)

                    print(f"File: {file_name}, Solved in {steps} steps")
                else:
                    # Cannot be solved (Wrong/invalid puzzle)
                    # Reasons can be invalid puzzle or grid/digits detected wrongly
                    print(
                        f"File: {file_name}, Invalid puzzle or digit detection error"
                    )
            else:
                # Unable to tally 81 boxes
                print(f"File: {file_name}: Unable to detect 81 cells in grid")

        else:
            # Fail to detect grid
            print(f"File: {file_name}, Unable to detect grid")