Beispiel #1
0
    def __init__(self, img):
        self.matrix = FlowMatrix(img)

        print self.matrix.gridsize
        print self.matrix.colours

        self.matrix.printMatrix()

        self.solve()
Beispiel #2
0
    def __init__(self, img):
        self.matrix = FlowMatrix(img)

        print self.matrix.gridsize
        print self.matrix.colours

        self.matrix.printMatrix()

        self.solve()
Beispiel #3
0
class Flow:

    def __init__(self, img):
        self.matrix = FlowMatrix(img)

        print self.matrix.gridsize
        print self.matrix.colours

        self.matrix.printMatrix()

        self.solve()

    def solve(self):

        def solveGrid(solutions, grid_size):
            
            output = []
            max = len(solutions)-1

            def cartesian(arr, i):
                
                for solution in solutions[i]:

                    a = arr[:]
                    a.append(solution)

                    if i == max:
                        # Certesian Product found
                        if checkSolution(a, grid_size):
                            output.append(a)
                            return
                    else:
                        # Recurse
                        cartesian(a, i+1)

            def checkSolution(solutions, grid_size):

                # Flatten list of solutions
                b = sum(solutions,[])

                # Solution must fill entire grid
                if len(b) != (grid_size * grid_size):
                    return False

                # Solution must not overlap another grid cell
                return (len(b) - len(set(b))) == 0

            cartesian([],0)
            
            return output

        def search(maze, x, y):

            if (x,y) == self.end:
                # Found a solution
                return True
            elif maze[x][y] == True:
                # Hit a wall
                return False
            elif maze[x][y] == 3:
                return False

            # mark as visited
            maze[x][y] = 3

            # explore neighbors clockwise starting by the one on the right
            if ((x < len(maze)-1 and search(maze, x+1, y))
                or (y > 0 and search(maze, x, y-1))
                or (x > 0 and search(maze, x-1, y))
                or (y < len(maze)-1 and search(maze, x, y+1))):
                return True

            return False

        def checkIfPathConflicts(paths):

            colours = copy.deepcopy(self.matrix.colours)
            colours.pop(colour_index)

            for c in colours:

                dupe = copy.deepcopy(self.matrix.matrix)

                for path in paths:
                    self.matrix.toggleCell(dupe, path)

                self.matrix.toggleCell(dupe, c[0])
                self.matrix.toggleCell(dupe, c[1])
                
                self.end = c[1]

                if search(dupe, c[0][0], c[0][1]) == False:
                    return True
                    

            return False

        def findPaths(maze, start, end):

            result = []
            if start.row < 0 or start.col < 0:
                return False
            if start.row == self.matrix.gridsize or start.col == self.matrix.gridsize:
                return False
            if maze[start.row][start.col] is 1:
                return False

            if start.isequals(end):
                # Start a new path
                result.append([start.tuple()])
                return result

            maze[start.row][start.col] = 1

            nextCells = [x[:] for x in ['']*4]
            nextCells[0] = Cell((start.row + 1, start.col))
            nextCells[2] = Cell((start.row, start.col + 1))
            nextCells[1] = Cell((start.row - 1, start.col))
            nextCells[3] = Cell((start.row, start.col - 1))

            for nextCell in nextCells:
                paths = findPaths(maze, nextCell, end)
                if paths is not False:
                    for i, (path) in enumerate(paths):
                        path.append(start.tuple())

                        if start.tuple() == start_colour:
                            if checkIfPathConflicts(paths[i]):
                                paths[i] = []
                    
                    result.extend(paths)

            maze[start.row][start.col] = 0

            if len(result) == 0:
                return False
            
            return result

        fortest = []

        for i, (co) in enumerate(self.matrix.colours):
            
            for cell in co:
                self.matrix.toggleCell(self.matrix.matrix, cell)

            start_colour = co[0]
            colour_index = i

            paths = findPaths(self.matrix.matrix, Cell(co[0]), Cell(co[1]))

            if paths:
                fortest.append(filter(None, paths))
            
            for cell in co:
                self.matrix.toggleCell(self.matrix.matrix, cell)

        print solveGrid(fortest, self.matrix.gridsize)
Beispiel #4
0
class Flow:
    def __init__(self, img):
        self.matrix = FlowMatrix(img)

        print self.matrix.gridsize
        print self.matrix.colours

        self.matrix.printMatrix()

        self.solve()

    def solve(self):
        def solveGrid(solutions, grid_size):

            output = []
            max = len(solutions) - 1

            def cartesian(arr, i):

                for solution in solutions[i]:

                    a = arr[:]
                    a.append(solution)

                    if i == max:
                        # Certesian Product found
                        if checkSolution(a, grid_size):
                            output.append(a)
                            return
                    else:
                        # Recurse
                        cartesian(a, i + 1)

            def checkSolution(solutions, grid_size):

                # Flatten list of solutions
                b = sum(solutions, [])

                # Solution must fill entire grid
                if len(b) != (grid_size * grid_size):
                    return False

                # Solution must not overlap another grid cell
                return (len(b) - len(set(b))) == 0

            cartesian([], 0)

            return output

        def search(maze, x, y):

            if (x, y) == self.end:
                # Found a solution
                return True
            elif maze[x][y] == True:
                # Hit a wall
                return False
            elif maze[x][y] == 3:
                return False

            # mark as visited
            maze[x][y] = 3

            # explore neighbors clockwise starting by the one on the right
            if ((x < len(maze) - 1 and search(maze, x + 1, y))
                    or (y > 0 and search(maze, x, y - 1))
                    or (x > 0 and search(maze, x - 1, y))
                    or (y < len(maze) - 1 and search(maze, x, y + 1))):
                return True

            return False

        def checkIfPathConflicts(paths):

            colours = copy.deepcopy(self.matrix.colours)
            colours.pop(colour_index)

            for c in colours:

                dupe = copy.deepcopy(self.matrix.matrix)

                for path in paths:
                    self.matrix.toggleCell(dupe, path)

                self.matrix.toggleCell(dupe, c[0])
                self.matrix.toggleCell(dupe, c[1])

                self.end = c[1]

                if search(dupe, c[0][0], c[0][1]) == False:
                    return True

            return False

        def findPaths(maze, start, end):

            result = []
            if start.row < 0 or start.col < 0:
                return False
            if start.row == self.matrix.gridsize or start.col == self.matrix.gridsize:
                return False
            if maze[start.row][start.col] is 1:
                return False

            if start.isequals(end):
                # Start a new path
                result.append([start.tuple()])
                return result

            maze[start.row][start.col] = 1

            nextCells = [x[:] for x in [''] * 4]
            nextCells[0] = Cell((start.row + 1, start.col))
            nextCells[2] = Cell((start.row, start.col + 1))
            nextCells[1] = Cell((start.row - 1, start.col))
            nextCells[3] = Cell((start.row, start.col - 1))

            for nextCell in nextCells:
                paths = findPaths(maze, nextCell, end)
                if paths is not False:
                    for i, (path) in enumerate(paths):
                        path.append(start.tuple())

                        if start.tuple() == start_colour:
                            if checkIfPathConflicts(paths[i]):
                                paths[i] = []

                    result.extend(paths)

            maze[start.row][start.col] = 0

            if len(result) == 0:
                return False

            return result

        fortest = []

        for i, (co) in enumerate(self.matrix.colours):

            for cell in co:
                self.matrix.toggleCell(self.matrix.matrix, cell)

            start_colour = co[0]
            colour_index = i

            paths = findPaths(self.matrix.matrix, Cell(co[0]), Cell(co[1]))

            if paths:
                fortest.append(filter(None, paths))

            for cell in co:
                self.matrix.toggleCell(self.matrix.matrix, cell)

        print solveGrid(fortest, self.matrix.gridsize)