示例#1
0
    def testIndependentSet(self):
        n = 100
        e = 5 * n
        g = UndirectedGraph()
        for i in range(e):
            u = int(random() * n)
            v = int(random() * n)
            if u == v:
                continue
            if not g.contains(u):
                g.add_node(u)
            if not g.contains(v):
                g.add_node(v)
            g.connect(u, v)

        ind_set = g.independent_set(8)
        for i in ind_set:
            neighbors = g.e[i]
            self.assertEqual(neighbors.intersection(ind_set), set([]))
示例#2
0
        def remove_independent_set(regions):
            """
                Processes a set of regions, detecting and removing an independent set
                of vertices from the regions' graph representation, and re-triangulating
                the resulting holes.

                Arguments:
                regions -- a set of non-overlapping polygons that tile some part of the plane

                Returns: a new set of regions covering the same subset of the plane, with fewer vertices
            """
            # Take note of which points are in which regions
            points_to_regions = {}
            for idx, region in enumerate(regions):
                for point in region.points:
                    if point in points_to_regions:
                        points_to_regions[point].add(idx)
                        continue

                    points_to_regions[point] = set([idx])

            # Connect graph
            g = UndirectedGraph()
            for region in regions:
                for idx in range(region.n):
                    u = region.points[idx % region.n]
                    v = region.points[(idx + 1) % region.n]
                    if not g.contains(u):
                        g.add_node(u)
                    if not g.contains(v):
                        g.add_node(v)
                    g.connect(u, v)

            # Avoid adding points from outer triangle
            removal = g.independent_set(8, avoid=bounding_triangle.points)

            # Track unaffected regions
            unaffected_regions = set([i for i in range(len(regions))])
            new_regions = []
            for p in removal:
                # Take note of affected regions
                affected_regions = points_to_regions[p]
                unaffected_regions.difference_update(points_to_regions[p])

                def calculate_bounding_polygon(p, affected_regions):
                    edges = []
                    point_locations = {}
                    for j, i in enumerate(affected_regions):
                        edge = set(regions[i].points)
                        edge.remove(p)
                        edges.append(edge)
                        for v in edge:
                            if v in point_locations:
                                point_locations[v].add(j)
                            else:
                                point_locations[v] = set([j])

                    boundary = []
                    edge = edges.pop()
                    for v in edge:
                        point_locations[v].remove(len(edges))
                        boundary.append(v)
                    for k in range(len(affected_regions) - 2):
                        v = boundary[-1]
                        i = point_locations[v].pop()
                        edge = edges[i]
                        edge.remove(v)
                        u = edge.pop()
                        point_locations[u].remove(i)
                        boundary.append(u)

                    return shapes.Polygon(boundary)

                # triangulate hole
                poly = calculate_bounding_polygon(p, affected_regions)
                triangles = spatial.triangulatePolygon(poly)
                for triangle in triangles:
                    self.dag.add_node(triangle)
                    for j in affected_regions:
                        region = regions[j]
                        self.dag.connect(triangle, region)
                    new_regions.append(triangle)

            for i in unaffected_regions:
                new_regions.append(regions[i])

            return new_regions