Ejemplo n.º 1
0
Archivo: Maze.py Proyecto: timchow/Maze
    def MakeMaze(self, width, height):
        self.width = width
        self.height = height
        self.canvasWidth = width * self.SCALE_FACTOR
        self.canvasHeight = height * self.SCALE_FACTOR
        self.disjointSets = DisjointSets(width * height)
        self.mazeCells = [[MazeCell(x, y) for y in range(height)]
                          for x in range(width)]

        Xs = list(range(self.width))
        Ys = list(range(self.height))
        # cartesian product X x Y
        randomCoords = list(itertools.product(Xs, Ys))
        randomCoords.extend(randomCoords)
        random.shuffle(randomCoords)

        for (row, column) in randomCoords:
            mazeCell = self.mazeCells[row][column]
            wallRemoveDirection = random.sample(
                [Direction.RIGHT, Direction.DOWN], 1)[0]

            if (mazeCell.visitedCount == 1):
                wallRemoveDirection = Direction.RIGHT if mazeCell.rightWallExists else Direction.DOWN

            a = self._findSetIndex(row, column)
            b = self._findSetIndex(row, column, wallRemoveDirection)

            if (self._checkBoundary(row, column, wallRemoveDirection)
                    and self.disjointSets.SetUnion(a, b)):
                self._setWall(mazeCell, wallRemoveDirection, False)

            mazeCell.visitedCount += 1
Ejemplo n.º 2
0
def makemaze(w,h,tw):
  random.seed()
  size = w*h
  ds = DisjointSets(size)
  walls = ([(a,a+1) for a in [x for x in range(size) if (x+1)%w != 0]]
          + [(a,a+w) for a in [x for x in range(size-w)]])
  while not _done(ds):
    a,b = walls[random.randint(0, len(walls)-1)]
    x,y = ds.find(a), ds.find(b)
    if not x == y:
      ds.union(x,y)
      walls.remove((a,b))

  tiles = ([Tile('wall',_newp(i,tw),_newp(j,tw),tw) for i in range(2*w+1) for j in range(2*h+1)
           if (i == 0 or j == 0 or i == w*2 or j == h*2 or (i%2==0 and j%2==0))
           and not (j == 2*h-1 and i == 2*w)]
           + [Tile('floor',_newp(i,tw),_newp(j,tw),tw) 
              for i in range(1,2*w+1) for j in range(1,2*h+1)
              if (i%2==1 and j%2==1)
              or (j == 2*h-1 and i == 2*w)]
           + [Tile('wall' if i%2==0 and
                            list(set([(a,a+1) for a in range(i/2-1,size,w)])
                             & set([(b,b+1) for b in 
                                range(j/2*w,(j/2+1)*w-1)]))[0] in walls
                          or i%2==1 and
                            list(set([(a,a+w) for a in range(i/2,size,w)])
                            & set([(b,b+w) for b in 
                               range((j/2-1)*w,j/2*w)]))[0] in walls
                          else 'floor'
                   ,_newp(i,tw),_newp(j,tw),tw) 
              for i in range(1,2*w) for j in range(1,2*h)
              if i%2 != j%2])

  return tiles
Ejemplo n.º 3
0
    def test_SetUnion(self):
        numElements = 5
        test = DisjointSets(numElements)

        self.assertEqual(test.SetUnion(0, 2), True)
        self.assertEqual(test.uptrees, [2, -1, -2, -1, -1])

        self.assertEqual(test.SetUnion(0, 2), False)
        self.assertEqual(test.uptrees, [2, -1, -2, -1, -1])

        self.assertEqual(test.SetUnion(1, 2), True)
        self.assertEqual(test.uptrees, [2, 2, -3, -1, -1])

        self.assertEqual(test.SetUnion(4, 4), False)
        self.assertEqual(test.uptrees, [2, 2, -3, -1, -1])

        self.assertEqual(test.SetUnion(5, 5), False)
        self.assertEqual(test.uptrees, [2, 2, -3, -1, -1])

        self.assertEqual(test.SetUnion(3, 4), True)
        self.assertEqual(test.uptrees, [2, 2, -3, 4, -2])

        self.assertEqual(test.SetUnion(0, 3), True)
        self.assertEqual(test.uptrees, [2, 2, -5, 4, 2])

        self.assertEqual(test.SetUnion(-1, -2), False)
        self.assertEqual(test.uptrees, [2, 2, -5, 4, 2])
Ejemplo n.º 4
0
    def test_FindRoot(self):
        numElements = 5
        test = DisjointSets(numElements)
        test.uptrees = [2, 2, -4, -1, 2]

        self.assertEqual(test.FindRoot(2), 2)
        self.assertEqual(test.FindRoot(0), 2)
        self.assertEqual(test.FindRoot(-1), -1)
Ejemplo n.º 5
0
def mst(n, edges):
    weight_sum, m, tree = 0, n - 1, []
    edges.sort(key=lambda x: -x[2])
    sets = DS()
    vertices = [sets.make_set(i) for i in range(n)]
    while m > 0:
        edge = edges.pop()
        if not sets.union(vertices[edge[0]], vertices[edge[1]]):
            continue
        tree.append(edge)
        weight_sum += edge[2]
        m -= 1
    return tree, weight_sum
Ejemplo n.º 6
0
 def __init__(self, meta=None, fields=tuple()):
     if meta is None:
         meta = {}
     self.meta = meta
     self.fields = list(fields)
     self.instances = WeakCollection()
     # Each set of linked subfields means that those subfields are linked and share the same instance
     self.links = DisjointSets()
Ejemplo n.º 7
0
    def nbr_clustering(self, I, r):
        ''' Epsilon ball clustering 
        
        Parameters:
        ----------
        I: int, array
            The indices of elements to be clustered
        r: float, scale
            The distance threshold
        '''

        ds = DisjointSets(I)
        n_data = len(I)
        for i in range(n_data):
            for j in range(i + 1, n_data):
                if self.distM[I[i], I[j]] <= r:
                    ds.merge_byelm(I[i], I[j])
                    
        return ds
Ejemplo n.º 8
0
class Class(object):
    def __init__(self, meta=None, fields=tuple()):
        if meta is None:
            meta = {}
        self.meta = meta
        self.fields = list(fields)
        self.instances = WeakCollection()
        # Each set of linked subfields means that those subfields are linked and share the same instance
        self.links = DisjointSets()
        
    def __repr__(self):
        return '<%s, meta=%r, fields=%r>' % (self.__class__.__name__, self.meta, len(self.fields))

    def add_field(self, field):
        self.fields.append(field)
        for instance in self.instances:
            instance.new_field(field)
        
    def create_instance(self, **kw):
        instance = Instance(self, **kw)
        self.instances.add(instance)
        return instance

    def union(self, src_subfield_hierarchy, dst_subfield_hierarchy):
        src_subfield_hierarchy = tuple(src_subfield_hierarchy)
        dst_subfield_hierarchy = tuple(dst_subfield_hierarchy)
        self.links.union(src_subfield_hierarchy, dst_subfield_hierarchy)
        assert dst_subfield_hierarchy in self.links.set_of(src_subfield_hierarchy)
        assert src_subfield_hierarchy in self.links.set_of(dst_subfield_hierarchy)
        
        for instance in self.instances:
            # Find the subfield's_instance for this instance (extract the instance from the deepest level)
            src_subfield_instance = instance.get_subfield_instance(src_subfield_hierarchy, False)
            
            # Tell the instance that the subfield has changed, it will update all internally linked fields to point
            # to the new instance.
            instance.subfield_linked(src_subfield_hierarchy, src_subfield_instance)

    def split(self, subfield_hierarchy):
        self.links.split(subfield_hierarchy)
        for instance in self.instances:
            instance.subfield_unlinked(subfield_hierarchy)
Ejemplo n.º 9
0
def kruskal(graph):
    """Find the minimum spanning tree of a graph."""
    msf = set()

    forest = DisjointSets()
    for v in graph.keys():
        forest.makeset(v)

    edges = []
    for u, adjlist in graph.items():
        for (v, weight) in adjlist.items():
            edges.append((u, v, weight))
    edges.sort(key=lambda edge: edge[2])

    for u, v, w in edges:
        if forest.find(u) != forest.find(v):
            msf.add((u, v, w))
            forest.union(u, v)

    return msf
Ejemplo n.º 10
0
def kruskal(graph):
    """Find the minimum spanning tree of a graph."""
    msf = set()

    forest = DisjointSets()
    for v in graph.keys():
        forest.makeset(v)

    edges = []
    for u, adjlist in graph.items():
        for (v, weight) in adjlist.items():
            edges.append((u, v, weight))
    edges.sort(key=lambda edge: edge[2])

    for u, v, w in edges:
        if forest.find(u) != forest.find(v):
            msf.add((u, v, w))
            forest.union(u, v)
    
    return msf
Ejemplo n.º 11
0
def kruskal(G):
    aristas = G.aristas()
    aristas.sort()
    D = DisjointSets(G.num_verts)
    return aristas_sin_ciclos(aristas, D)
Ejemplo n.º 12
0
Archivo: Maze.py Proyecto: timchow/Maze
class Maze(object):

    SCALE_FACTOR = 10

    def __init__(self, width=0, height=0):
        self.width = 0
        self.height = 0
        self.canvasWidth = 0
        self.canvasHeight = 0
        self.mazeCells = []

        self.MakeMaze(width, height)

    def MakeMaze(self, width, height):
        self.width = width
        self.height = height
        self.canvasWidth = width * self.SCALE_FACTOR
        self.canvasHeight = height * self.SCALE_FACTOR
        self.disjointSets = DisjointSets(width * height)
        self.mazeCells = [[MazeCell(x, y) for y in range(height)]
                          for x in range(width)]

        Xs = list(range(self.width))
        Ys = list(range(self.height))
        # cartesian product X x Y
        randomCoords = list(itertools.product(Xs, Ys))
        randomCoords.extend(randomCoords)
        random.shuffle(randomCoords)

        for (row, column) in randomCoords:
            mazeCell = self.mazeCells[row][column]
            wallRemoveDirection = random.sample(
                [Direction.RIGHT, Direction.DOWN], 1)[0]

            if (mazeCell.visitedCount == 1):
                wallRemoveDirection = Direction.RIGHT if mazeCell.rightWallExists else Direction.DOWN

            a = self._findSetIndex(row, column)
            b = self._findSetIndex(row, column, wallRemoveDirection)

            if (self._checkBoundary(row, column, wallRemoveDirection)
                    and self.disjointSets.SetUnion(a, b)):
                self._setWall(mazeCell, wallRemoveDirection, False)

            mazeCell.visitedCount += 1

    def _resetMazeCells(self):
        for row in range(self.height):
            for col in range(self.width):
                self.mazeCells[row][col].marked = False

    def _findSetIndex(self, row, column, direction=Direction.NONE):
        if direction is Direction.NONE:
            return (row * self.width) + column

        return (row *
                self.width) + column + 1 if direction is Direction.RIGHT else (
                    (row + 1) * self.width) + column

    def _setWall(self, mazeCell, direction, exists):
        if (direction is Direction.RIGHT):
            mazeCell.rightWallExists = exists
        elif (direction is Direction.DOWN):
            mazeCell.downWallExists = exists

    def DrawSolution(self, pixels, solution):
        currentRow = self.SCALE_FACTOR // 2
        currentCol = self.SCALE_FACTOR // 2

        for step in solution.path:
            cv2.imshow('image', pixels)
            if (step is Direction.DOWN):
                self._colorWall(pixels, Orientation.VERTICAL, currentRow,
                                currentRow + self.SCALE_FACTOR, currentCol,
                                Color.RED)
                currentRow += self.SCALE_FACTOR

            elif (step is Direction.RIGHT):
                self._colorWall(pixels, Orientation.HORIZONTAL, currentCol,
                                currentCol + self.SCALE_FACTOR, currentRow,
                                Color.RED)
                currentCol += self.SCALE_FACTOR

            elif (step is Direction.LEFT):
                self._colorWall(pixels, Orientation.HORIZONTAL,
                                currentCol - self.SCALE_FACTOR, currentCol,
                                currentRow, Color.RED)
                currentCol -= self.SCALE_FACTOR

            elif (step is Direction.UP):
                self._colorWall(pixels, Orientation.VERTICAL,
                                currentRow - self.SCALE_FACTOR, currentRow,
                                currentCol, Color.RED)
                currentRow -= self.SCALE_FACTOR

            cv2.waitKey(0)

        currentRow += self.SCALE_FACTOR // 2
        currentCol -= self.SCALE_FACTOR // 2

        # Drawing exit
        self._colorWall(pixels, Orientation.HORIZONTAL, currentCol,
                        currentCol + self.SCALE_FACTOR, currentRow,
                        Color.WHITE)

    def _blackenCells(self, pixels):
        for row in range(self.height):
            for column in range(self.width):
                mazeCell = self.mazeCells[row][column]

                if (mazeCell.rightWallExists):
                    rowStart = (row * self.SCALE_FACTOR)
                    columnFixed = (column * self.SCALE_FACTOR
                                   ) + MazeCell.RIGHT_WALL_OFFSET_PX
                    self._colorWall(pixels, Orientation.VERTICAL, rowStart,
                                    rowStart + self.SCALE_FACTOR, columnFixed,
                                    Color.BLACK)

                if (mazeCell.downWallExists):
                    rowFixed = (
                        row * self.SCALE_FACTOR) + MazeCell.DOWN_WALL_OFFSET_PX
                    columnStart = (column * self.SCALE_FACTOR)
                    self._colorWall(pixels, Orientation.HORIZONTAL,
                                    columnStart,
                                    columnStart + self.SCALE_FACTOR, rowFixed,
                                    Color.BLACK)

    def _blackenTop(self, pixels):
        DOOR_OFFSET = 10
        self._colorWall(pixels, Orientation.HORIZONTAL, DOOR_OFFSET,
                        self.canvasWidth, 0, Color.BLACK)

    def _blackenLeft(self, pixels):
        self._colorWall(pixels, Orientation.VERTICAL, 0, self.canvasHeight, 0,
                        Color.BLACK)

    def _colorWall(self, pixels, orientation, start, end, fixedDimension,
                   color):
        if (orientation is Orientation.VERTICAL):
            for i in range(start, end):
                pixels[fixedDimension, i] = tuple(color)

        elif (orientation is Orientation.HORIZONTAL):
            for i in range(start, end):
                pixels[i, fixedDimension] = tuple(color)

    def _canTravel(self, row, column, direction):
        return self._checkBoundary(row, column, direction) and \
            not self._hasWall(row, column, direction) and \
            not self._isVisited(row, column, direction)

    def _isVisited(self, row, column, direction):
        if (direction is Direction.DOWN):
            return (self.mazeCells[row + 1][column].marked)
        elif (direction is Direction.RIGHT):
            return (self.mazeCells[row][column + 1].marked)
        elif (direction is Direction.LEFT):
            return (self.mazeCells[row][column - 1].marked)
        elif (direction is Direction.UP):
            return (self.mazeCells[row - 1][column].marked)

    def _checkBoundary(self, row, column, direction):
        MIN_HEIGHT, MIN_WIDTH = 0, 0
        MAX_HEIGHT = self.height - 1
        MAX_WIDTH = self.width - 1

        if (direction is Direction.DOWN):
            return (row + 1 <= MAX_HEIGHT)
        elif (direction is Direction.RIGHT):
            return (column + 1 <= MAX_WIDTH)
        elif (direction is Direction.LEFT):
            return (column - 1 >= MIN_WIDTH)
        elif (direction is Direction.UP):
            return (row - 1 >= MIN_HEIGHT)

    def _hasWall(self, row, column, direction):
        if (direction is Direction.RIGHT):
            return self.mazeCells[row][column].rightWallExists
        elif (direction is Direction.DOWN):
            return self.mazeCells[row][column].downWallExists
        elif (direction is Direction.LEFT):
            return self.mazeCells[row][column - 1].rightWallExists
        elif (direction is Direction.UP):
            return self.mazeCells[row - 1][column].downWallExists

    def DrawMaze_CV(self, mazeSolution):
        imageWidth = (self.canvasWidth) + 1
        imageHeight = (self.canvasHeight) + 1
        RGB_DIMENSION = 3
        # 2D array of 1D arays of length 3 for pixel representation
        pixels = np.repeat(255,imageWidth*imageHeight*RGB_DIMENSION).astype('u1') \
                    .reshape((imageWidth,imageHeight,RGB_DIMENSION))

        self._blackenTop(pixels)
        self._blackenLeft(pixels)
        self._blackenCells(pixels)
        self.DrawSolution(pixels, mazeSolution)
Ejemplo n.º 13
0
    def test_AddElements(self):
        numElements = 5
        test = DisjointSets(numElements)

        self.assertEqual(test.uptrees, list(np.repeat(-1, numElements)))