示例#1
0
    def test_ugraph_edges(self):
        # Checks for antisimetry
        g = UndirectedGraph.rand(5)
        self.assertTrue(g.is_antisymmetric())

        with self.assertRaises(IsNotUndirectedGraphError):
            UndirectedGraph(3, [[0, 0], [0, 2], [2, 0], [1, 0]])
示例#2
0
 def test_adj(self):
     graph = UndirectedGraph(5, [(0, 1), (2, 3), (0, 4)])
     self.assertEqual(graph.adj(0), [1, 4])
     self.assertEqual(graph.adj(1), [0])
     self.assertEqual(graph.adj(2), [3])
     self.assertEqual(graph.adj(3), [2])
     self.assertEqual(graph.adj(4), [0])
示例#3
0
def explore(graph: UndirectedGraph, reporter: Reporter) -> None:
    """Naive Bron-Kerbosch algorithm, optimized"""
    if candidates := graph.connected_vertices():
        visit(graph=graph,
              reporter=reporter,
              candidates=candidates,
              excluded=set(),
              clique=[])
示例#4
0
文件: io.py 项目: StatisKit/PGM
def from_networkx(ngraph):
    if ngraph.is_directed():
        raise NotImplementedError()
    else:
        graph = UndirectedGraph(ngraph.number_of_nodes())
        for edge in ngraph.edges_iter():
            graph.add_edge(int(edge[0]), int(edge[1]))
    return graph
def test_degeneracy_ordering_nonempty(adjacencies: List[Set[Vertex]]) -> None:
    g = UndirectedGraph(adjacencies=adjacencies)
    connected_vertices = g.connected_vertices()

    ordering = list(degeneracy_ordering(g))
    assert set(ordering) == connected_vertices
    assert all(g.degree(ordering[0]) <= g.degree(v) for v in ordering[1:])

    ordering_min1 = list(degeneracy_ordering(g, drop=1))
    assert ordering_min1 == ordering[:-1]
示例#6
0
def explore(graph: UndirectedGraph, reporter: Reporter) -> None:
    """Bron-Kerbosch algorithm with pivot of highest degree within remaining candidates
       chosen from candidates only (IK_GP)"""
    if candidates := graph.connected_vertices():
        visit(graph=graph,
              reporter=reporter,
              pivot_choice_X=False,
              candidates=candidates,
              excluded=set(),
              clique=[])
示例#7
0
def random_undirected_graph(order: int, size: int) -> UndirectedGraph:
    adjacencies: List[Set[Vertex]] = [set() for _ in range(order)]
    print(f"order={order}, size={size}")
    for v, w in generate_n_edges(order, size):
        adjacencies[v].add(w)
        adjacencies[w].add(v)
    print(adjacencies)
    g = UndirectedGraph(adjacencies=adjacencies)
    assert g.order == order
    assert g.size() == size
    return g
示例#8
0
 def test_find_shortest_path(self):
     dg = UndirectedGraph("A", "B", "C", "D")
     dg.add_new_edge("A", "B")
     dg.add_new_edge("B", "D")
     dg.add_new_edge("B", "C")
     dg.add_new_edge("A", "C")
     dg.add_new_edge("C", "D")
     result = dg.find_shortest_path("A", "D")
     assert result == [vt("A"), vt("B"), vt("D")] or result == [
         vt("A"), vt("C"), vt("D")
     ]
示例#9
0
def degeneracy_ordering(graph: UndirectedGraph,
                        drop: int = 0) -> Generator[Vertex, None, None]:
    """
    Iterate connected vertices, lowest degree first.
    drop=N: omit last N vertices
    """
    assert drop >= 0
    priority_per_node = [-2] * graph.order
    max_degree = 0
    num_candidates = 0
    for c in range(graph.order):
        if degree := graph.degree(c):
            priority_per_node[c] = degree
            max_degree = max(max_degree, degree)
            num_candidates += 1
示例#10
0
    def setUp(self):
        self.graph = UndirectedGraph()
        self.filled_graph = UndirectedGraph()

        for i in range(6):
            self.filled_graph.add_vertex(i + 1)

        self.filled_graph.add_edge(1, 2)
        self.filled_graph.add_edge(1, 4)
        self.filled_graph.add_edge(2, 4)
        self.filled_graph.add_edge(2, 3)
        self.filled_graph.add_edge(4, 3)
        self.filled_graph.add_edge(3, 6)
        self.filled_graph.add_edge(4, 5)
        self.filled_graph.add_edge(5, 6)
示例#11
0
 def test_load_graph_duplicate_non_conflicting_lines(self):
     try:
         UndirectedGraph(
             "test/graph-with-duplicate-non-conflicting-lines.csv")
     except ValueError:
         self.fail(
             "Graph file contains duplicate, but non-conflicting edges.")
示例#12
0
def main():
    graph_filename = input("Graph filename: ")
    graph = UndirectedGraph(graph_filename)

    start_node = input("Start node: ")
    end_node = input("End node: ")

    shortest_path = graph.shortest_path(start_node, end_node)
    path = shortest_path['path']
    cost = shortest_path['cost']

    if path is None:
        print(f"There is no path connecting {start_node} to {end_node}.")
    else:
        print(
            f"Path from {start_node} to {end_node} is {path_to_string(path)},",
            f"and have cost {cost}.")
示例#13
0
    def test_traverse(self):
        vertexes_names = []

        def traverse_visit_callback(vertex):
            vertexes_names.append(vertex.name)

        un = UndirectedGraph("A", "B", "C", "D")
        un.add_new_edge("A", "B")
        un.add_new_edge("B", "C")
        un.add_new_edge("C", "D")

        # bfs
        un.bfs_traverse("A", traverse_visit_callback)
        assert vertexes_names == ["A", "B", "C", "D"]
        vertexes_names = []
        # dfs
        un.dfs_traverse("A", traverse_visit_callback)
        assert vertexes_names == ["A", "B", "C", "D"]
示例#14
0
def journeyToMoon(n, astronaut):
    '''
    Function signature supplied by Hackerrank,
    and my implementation using supplied arguments: n, astronaut.
    '''
    graph = UndirectedGraph(n, astronaut)
    subset_sizes = disjoint_subset_sizes(graph)

    return number_of_pairs(subset_sizes)
def visit(graph: UndirectedGraph, reporter: Reporter, pivot_choice_X: bool,
          candidates: Set[Vertex], excluded: Set[Vertex],
          clique: List[Vertex]) -> None:
    assert all(graph.degree(v) > 0 for v in candidates)
    assert all(graph.degree(v) > 0 for v in excluded)
    assert candidates.isdisjoint(excluded)
    assert len(candidates) >= 1
    if len(candidates) == 1:
        # Same logic as below, stripped down for this common case
        for v in candidates:
            neighbours = graph.adjacencies[v]
            assert neighbours
            if excluded.isdisjoint(neighbours):
                reporter.record(clique + [v])
        return

    # Quickly handle locally unconnected candidates while finding pivot
    remaining_candidates = []
    seen_local_degree = 0
    for v in candidates:
        neighbours = graph.adjacencies[v]
        local_degree = len(candidates.intersection(neighbours))
        if local_degree == 0:
            # Same logic as below, stripped down
            if neighbours.isdisjoint(excluded):
                reporter.record(clique + [v])
        else:
            if seen_local_degree < local_degree:
                seen_local_degree = local_degree
                pivot = v
            remaining_candidates.append(v)
    if seen_local_degree == 0:
        return
    if pivot_choice_X:
        for v in excluded:
            neighbours = graph.adjacencies[v]
            local_degree = len(candidates.intersection(neighbours))
            if seen_local_degree < local_degree:
                seen_local_degree = local_degree
                pivot = v

    for v in remaining_candidates:
        neighbours = graph.adjacencies[v]
        assert neighbours
        if pivot not in neighbours:
            candidates.remove(v)
            if neighbouring_candidates := candidates.intersection(neighbours):
                neighbouring_excluded = excluded.intersection(neighbours)
                visit(graph=graph,
                      reporter=reporter,
                      pivot_choice_X=pivot_choice_X,
                      candidates=neighbouring_candidates,
                      excluded=neighbouring_excluded,
                      clique=clique + [v])
            elif excluded.isdisjoint(neighbours):
                reporter.record(clique + [v])
            excluded.add(v)
示例#16
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([]))
示例#17
0
def read_random_graph(orderstr: str,
                      size: Optional[int]) -> Tuple[UndirectedGraph, int]:
    order = to_int(orderstr)
    fully_meshed_size = order * (order - 1) // 2
    if size is None:
        size = fully_meshed_size
    elif size > fully_meshed_size:
        raise ValueError(
            f"{order} nodes accommodate at most {fully_meshed_size} edges")
    edges_name = f"random_edges_order_{orderstr}"
    stats_name = f"random_stats"
    edges_path = os.path.join(os.pardir, "data", edges_name + ".txt")
    stats_path = os.path.join(os.pardir, "data", stats_name + ".txt")
    adjacencies = read_edges(edges_path, orderstr, order, size)
    clique_count = read_stats(stats_path, orderstr, size)
    g = UndirectedGraph(adjacencies=adjacencies)
    assert g.order == order
    assert g.size() == size
    return g, clique_count
示例#18
0
def dijkstra(g: UndirectedGraph, initial_node: int = 0) -> List[int]:
    """
    Initialise all distances to infinity, except for initial_node which is 0.
    
    For each unseen vertex:
        - cur: vertex with minimal distance.
        - Mark cur as seen.

        - For each unseen neighbour of cur:
            - alt: cumulative distance to cur + distance to neighbour.
            - If alt < dist[neighbour]:
                - Set dist[neighbour] = alt
                - Set prev[neighbour] = cur

            # We have essentially found a better way to reach this neighbour.
            # We progressively update this until we have the best way 
            # to reach this node from our initial node.
    """

    dist = [math.inf for _ in range(g.num_vertices)]
    dist[initial_node] = 0
    prev = [None for _ in range(g.num_vertices)]
    unseen_vertices = [v for v in range(g.num_vertices)]

    while unseen_vertices:
        min_node, min_value = unseen_vertices[0], dist[0]
        for v in unseen_vertices:
            if dist[v] < min_value:
                min_node, min_value = v, dist[v]
        cur = min_node

        unseen_vertices.remove(cur)

        for neighbour in g.get_neighbours(cur):
            if neighbour in unseen_vertices:
                alt = dist[cur] + g.get_weight(cur, neighbour)
                if alt < dist[neighbour]:
                    dist[neighbour] = alt
                    prev[neighbour] = cur

    return dist, prev
示例#19
0
    def test_simple(self):
        graph = UndirectedGraph(4)

        graph.add(0, 1, 10)
        graph.add(0, 2, 4)
        graph.add(1, 2, 5)
        graph.add(1, 3, 6)
        graph.add(2, 3, 5)

        value = stoer_wagner(graph)

        expected_value = 11  # (0, 1, 2) & 3

        self.assertEqual(value, expected_value)
示例#20
0
	def __init__(self):
		self.walls  = {}
		self.starts = []
		self.goals  = []
		self.keys   = []

		self.max_cols = None
		self.max_rows = None

		self.undirected_graph = UndirectedGraph()
		self.directed_graph = DirectedGraph()
		self.distance_node = {}
		self.node_distance = {}
 def createEdge(self, vertex):
     vertexLoc = vertex.data
     try:
         boundary = self.whichBoundary(vertex)
         if boundary == 'BOTTOMRIGHT':
             return
         for rowOffset, colOffset in MOVES[boundary]:
             v = self.vertices.find_by_data(
                 (vertexLoc[0] + rowOffset, vertexLoc[1] + colOffset))
             edge = UndirectedGraph.Edge(1, vertex, v)
             self.add_edge(edge)
     except KeyError:
         return
示例#22
0
    def test_adjacency_matrix(self):
        ug = UndirectedGraph("A", "B", "C", "D")
        ug.add_new_edge("A", "B")
        ug.add_new_edge("B", "C")
        ug.add_new_edge("C", "D")

        assert ug.adjacency_matrix == [[0, 1, 0, 0], [1, 0, 1, 0],
                                       [0, 1, 0, 1], [0, 0, 1, 0]]
示例#23
0
    def test_create(self):
        ug = UndirectedGraph("A", "B", "C")
        ug.add_new_edge("A", "B")
        ug.add_new_edge("B", "C")

        assert [v.name for v in ug.vertexes] == ["A", "B", "C"]
        assert ug.adjacency_dict == {
            vt("A"): [vt("B")],
            vt("B"): [vt("A"), vt("C")],
            vt("C"): [vt("B")]
        }

        with pytest.raises(exceptions.VertexNotExistError):
            ug.get_vertex_by_name("E")

        with pytest.raises(exceptions.VertexNotExistError):
            ug.add_new_edge("C", "E")
示例#24
0
class SymmetricHopfieldNetwork(object):
    """
    The SymmetricHopfieldNetwork is a edge weighted graph with binary units
    on the vertecies. The energy of the network is calculated by adding the
    edge weight between two activated units and then adding a bias term to 
    activated units.
    """

    weights = None  # EdgeWeightedGraph
    units = None
    biases = None

    def __init__(self, V):
        self.weights = UndirectedGraph(V)
        self.units = numpy.random.random(V) < 0.5
        self.biases = numpy.zeros(V)

    @property
    def size(self):
        return len(self.units)

    @property
    def polarization(self):
        """Average number of activated units."""
        return numpy.mean(self.units)

    @property
    def gaps(self):
        """Energy gaps for each unit to go from True --> False."""
        return self.biases + self.weights.matrix.dot(self.units)

    @property
    def energy(self):
        """Total energy of the network."""
        return numpy.dot(
            self.units,
            self.biases + 0.5 * self.weights.matrix.dot(self.units))

    def __str__(self):
        ret = 'Units: ' + self.units.__str__() + linesep
        ret += 'Biases: ' + self.biases.__str__() + linesep
        ret += 'Weights: ' + self.weights.__str__() + linesep
        ret += 'Energy: ' + self.energy.__str__() + linesep
        return ret
示例#25
0
class SymmetricHopfieldNetwork(object):
    """
    The SymmetricHopfieldNetwork is a edge weighted graph with binary units
    on the vertecies. The energy of the network is calculated by adding the
    edge weight between two activated units and then adding a bias term to 
    activated units.
    """
    
    weights = None # EdgeWeightedGraph
    units = None
    biases = None
        
    def __init__(self, V):
        self.weights = UndirectedGraph(V)
        self.units = numpy.random.random(V) < 0.5
        self.biases = numpy.zeros(V)
    
    @property
    def size(self):
        return len(self.units)
    
    @property
    def polarization(self):
        """Average number of activated units."""
        return numpy.mean(self.units)
    
    @property
    def gaps(self):
        """Energy gaps for each unit to go from True --> False."""
        return self.biases + self.weights.matrix.dot(self.units)
    
    @property
    def energy(self):
        """Total energy of the network."""
        return numpy.dot(self.units, self.biases + 0.5 * self.weights.matrix.dot(self.units))

    def __str__(self):
        ret = 'Units: ' + self.units.__str__() + linesep
        ret += 'Biases: ' + self.biases.__str__() + linesep
        ret += 'Weights: ' + self.weights.__str__() + linesep
        ret += 'Energy: ' + self.energy.__str__() + linesep
        return ret
示例#26
0
def visit(graph: UndirectedGraph, reporter: Reporter, candidates: Set[Vertex],
          excluded: Set[Vertex], clique: List[Vertex]) -> None:
    assert all(graph.degree(v) > 0 for v in candidates)
    assert all(graph.degree(v) > 0 for v in excluded)
    assert candidates.isdisjoint(excluded)
    assert candidates
    while candidates:
        v = candidates.pop()
        neighbours = graph.adjacencies[v]
        neighbouring_candidates = candidates.intersection(neighbours)
        if neighbouring_candidates:
            neighbouring_excluded = excluded.intersection(neighbours)
            visit(graph,
                  reporter,
                  candidates=neighbouring_candidates,
                  excluded=neighbouring_excluded,
                  clique=clique + [v])
        elif excluded.isdisjoint(neighbours):
            reporter.record(clique + [v])
        excluded.add(v)
示例#27
0
def build_graph(adj, features, labels):
    edges = np.array(adj.nonzero()).T
    y_values = np.array(labels.nonzero()).T

    domain_labels = []
    for i in range(labels.shape[1]):
        domain_labels.append("c" + str(i))

    # create graph
    graph = UndirectedGraph()
    id_obj_map = []
    for i in range(adj.shape[0]):
        n = Node(i, features[i, :], domain_labels[y_values[i, 1]])
        graph.add_node(n)
        id_obj_map.append(n)
    for e in edges:
        graph.add_edge(Edge(id_obj_map[e[1]], id_obj_map[e[0]]))

    return graph, domain_labels
 def createVertices(self):
     for r in range(self.size):
         for c in range(self.size):
             vertex = UndirectedGraph.Vertex((r, c))
             self.add_vertex(vertex)
示例#29
0
            if child not in self.depth:
                # (node -> child) is a forward edge
                self.dfs(child, current_depth + 1)
                self.low[node] = min(self.low[node], self.low[child])
                self._edge_stack.append((node, child))

                if self.low[child] >= current_depth:
                    self.articulations.add(node)

                    # Each articulation point closes a biconnected component.
                    self._current_bcc += 1
                    while self._edge_stack:
                        i, j = self._edge_stack[-1]
                        if max(self.depth[i], self.depth[j]) > current_depth:
                            self.bcc[self._edge_stack.pop()] = self._current_bcc
                        else:
                            break

                if self.low[child] > current_depth:
                    self.bridges.append((node, child))

            elif self.depth[child] < current_depth - 1:
                # (node -> child) is a back edge, update low[node]
                self.low[node] = min(self.low[node], self.depth[child])
                self._edge_stack.append((node, child))


if __name__ == '__main__':
    graph = UndirectedGraph.from_file('graph.in')
    bc = BiconnectedComponents(graph)
    bc.compute()
def test_degeneracy_ordering_empty() -> None:
    g = UndirectedGraph(adjacencies=[])
    assert list(degeneracy_ordering(g)) == []
    assert list(degeneracy_ordering(g, drop=1)) == []
示例#31
0
class FileLoader(object):
	def __init__(self):
		self.walls  = {}
		self.starts = []
		self.goals  = []
		self.keys   = []

		self.max_cols = None
		self.max_rows = None

		self.undirected_graph = UndirectedGraph()
		self.directed_graph = DirectedGraph()
		self.distance_node = {}
		self.node_distance = {}


	def read_map(self, file_name):
		print 'Reading File'
		f = open(file_name, 'r')

		# Reading walls: [row, col, up, left, down, right]
		print '\t> Parsing walls'

		[self.max_rows, self.max_cols] = f.readline().split(' ')
		self.max_rows = int(self.max_rows)
		self.max_cols = int(self.max_cols)

		for i in range(0, self.max_rows*self.max_cols):
			data = f.readline().split(' ')
			print 'data: ', data
			data = map(int, data)
			self.walls[(data[0],data[1])] = (data[2],data[3],data[4], data[5])

		# Reading starts
		print '\t> Parsing ', f.readline()
		MAX_START = int(f.readline())

		for i in range(0, MAX_START):
			data = f.readline().split(' ')
			if data[2][0] == 'u':
				orientation = 0
			elif data[2][0] == 'l':
				orientation = 1
			elif data[2][0] == 'd':
				orientation = 2
			else:
				orientation = 3
			self.starts.append((int(data[0]),int(data[1]),orientation))

		# Reading Goals
		print '\t> Parsing ', f.readline()
		MAX_GOALS = int(f.readline())

		for i in range(0, MAX_GOALS):
			data = f.readline().split(' ')
			row = int(data[0])
			col = int(data[1])
			self.goals.append((row,col))

		# Reading Keys
		print '\t> Parsing ', f.readline()
		MAX_KEYS = int(f.readline())

		for i in range(0, MAX_KEYS):
			data = f.readline().split(' ')
			row = int(data[0])
			col = int(data[1])
			self.keys.append((row,col))

		f.close()

	def generate_undirected_graph(self):
		orientations = [Orientation.up, Orientation.left, Orientation.down, Orientation.right]

		for w in self.walls.keys():
			row = w[0]
			col = w[1]

			for o in orientations:
				self.undirected_graph.add_node((row,col,o))

			self.undirected_graph.add_edge((row,col,Orientation.up),    (row,col,Orientation.left))
			self.undirected_graph.add_edge((row,col,Orientation.left),  (row,col,Orientation.down))
			self.undirected_graph.add_edge((row,col,Orientation.down),  (row,col,Orientation.right))
			self.undirected_graph.add_edge((row,col,Orientation.right), (row,col,Orientation.up))

		for node, ws in self.walls.items():
			if ws[0] == 0:
				self.undirected_graph.add_edge((node[0],node[1],Orientation.up), (node[0]+1,node[1],Orientation.up))
			if ws[1] == 0:
				self.undirected_graph.add_edge((node[0],node[1],Orientation.left), (node[0],node[1]-1,Orientation.left))
			if ws[2] == 0:
				self.undirected_graph.add_edge((node[0],node[1],Orientation.down), (node[0]-1,node[1],Orientation.down))
			if ws[3] == 0:
				self.undirected_graph.add_edge((node[0],node[1],Orientation.right), (node[0],node[1]+1,Orientation.right))

	def generate_directed_graph(self):
		orientations = [Orientation.up, Orientation.left, Orientation.down, Orientation.right]

		for w in self.walls.keys():
			row = w[0]
			col = w[1]

			for o in orientations:
				self.directed_graph.add_node((row,col,o))

			self.directed_graph.add_edge((row,col,Orientation.up),    (row,col,Orientation.left))
			self.directed_graph.add_edge((row,col,Orientation.left),    (row,col,Orientation.up))

			self.directed_graph.add_edge((row,col,Orientation.left),  (row,col,Orientation.down))
			self.directed_graph.add_edge((row,col,Orientation.down),  (row,col,Orientation.left))

			self.directed_graph.add_edge((row,col,Orientation.down),  (row,col,Orientation.right))
			self.directed_graph.add_edge((row,col,Orientation.right),  (row,col,Orientation.down))

			self.directed_graph.add_edge((row,col,Orientation.right), (row,col,Orientation.up))
			self.directed_graph.add_edge((row,col,Orientation.up), (row,col,Orientation.right))

		for node, ws in self.walls.items():
			if ws[0] == 0:
				self.directed_graph.add_edge((node[0],node[1],Orientation.up), (node[0]+1,node[1],Orientation.up))
			if ws[1] == 0:
				self.directed_graph.add_edge((node[0],node[1],Orientation.left), (node[0],node[1]-1,Orientation.left))
			if ws[2] == 0:
				self.directed_graph.add_edge((node[0],node[1],Orientation.down), (node[0]-1,node[1],Orientation.down))
			if ws[3] == 0:
				self.directed_graph.add_edge((node[0],node[1],Orientation.right), (node[0],node[1]+1,Orientation.right))

	def estimate_distances(self):
		#print '> Exploring distances'
		nodes = self.undirected_graph.nodes

		for node in nodes:
			#print '\t>>Localization::estimate_distances Node ', node
			distance = 0
			orientation = node[2]
			aux_node  = node
			test_node = node

			while True:
				if orientation == Orientation.up:
					test_node = (aux_node[0] + 1, aux_node[1], aux_node[2])
				elif orientation == Orientation.left:
					test_node = (aux_node[0], aux_node[1] - 1, aux_node[2])
				elif orientation == Orientation.down:
					test_node = (aux_node[0] - 1, aux_node[1], aux_node[2])
				elif orientation == Orientation.right:
					test_node = (aux_node[0], aux_node[1] + 1, aux_node[2])

				if not test_node in self.undirected_graph.edges[aux_node]: #BUG
					break
				aux_node = test_node
				distance = distance + 1

			self.distance_node.setdefault(distance, [])
			self.distance_node[distance].append(node)
			self.node_distance[node] = distance
示例#32
0
def dfs_iterative(graph, start_node):
    visited = [start_node]
    stack = [start_node]
    print('Visited', start_node)
    while stack != []:
        popped = stack.pop()
        if popped not in visited:
            print('Visited', popped)
            visited.append(popped)
        for node in graph.adjacents(popped):
            if node not in visited:
                stack.append(node)


if __name__ == '__main__':
    g = UndirectedGraph()
    g.add_edge(0, 1)
    g.add_edge(0, 2)
    g.add_edge(0, 3)
    g.add_edge(1, 4)
    g.add_edge(1, 5)
    g.add_edge(2, 6)
    g.add_edge(2, 7)
    g.add_edge(3, 7)

    bfs(g, 0)
    print('=' * 50)
    dfs(g, 0)
    print('=' * 50)
    dfs_iterative(g, 0)
示例#33
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
示例#34
0
 def __init__(self, V):
     self.weights = UndirectedGraph(V)
     self.units = numpy.random.random(V) < 0.5
     self.biases = numpy.zeros(V)
示例#35
0
文件: bfs.py 项目: jonas-mika/itu
                    self._marked[a] = True
                    self.queue.append(a)

    def has_path_to(self, v: int):
        return self._marked[v]

    def path_to(self, v: int):
        if self.has_path_to(v) == False: return None
        path = []
        x = v
        while x != self._s:
            path.append(x)
            x = self._edgeto[x]
        path.append(self._s)
        for i in reversed(path):
            print(f"{i}->", end='')

    def marked(self, v: int):
        return self._marked[v]


G1 = UndirectedGraph(5)
G1.add_edge(0, 1)
G1.add_edge(1, 2)
G1.add_edge(2, 3)
print(G1)
bfs = BFS(G1, 0)
print(bfs.has_path_to(3))
print(bfs.path_to(4))
print(bfs.path_to(3))
示例#36
0
	def create_map(self, file_name):
		walls = {}	

		print 'Reading File'
		f = open(file_name, 'r')

		# Reading walls: [row, col, up, left, down, right]
		print '\t> Parsing walls'
		[MAX_ROW, MAX_COL] = f.readline().split(' ')
		MAX_ROW = int(MAX_ROW)
		MAX_COL = int(MAX_COL)

		for i in range(0, MAX_ROW*MAX_COL):     
			data = f.readline().split(' ')
			print 'data: ', data
			data = map(int, data)
			walls[(data[0],data[1])] = (data[2],data[3],data[4], data[5])
		f.close()

		# Generating graph
		print 'Generating graph'
		graph = UndirectedGraph()
		for i in range(0, MAX_ROW):
			for j in range(0, MAX_COL):
				graph.add_node((i,j,Orientation.up))
				graph.add_node((i,j,Orientation.left))
				graph.add_node((i,j,Orientation.down))
				graph.add_node((i,j,Orientation.right))
				
				graph.add_edge((i,j,Orientation.up), (i,j,Orientation.left))
				graph.add_edge((i,j,Orientation.left), (i,j,Orientation.down))
				graph.add_edge((i,j,Orientation.down), (i,j,Orientation.right))
				graph.add_edge((i,j,Orientation.right), (i,j,Orientation.up))

		for node, ws in walls.items():
			if ws[0] == 0:
				graph.add_edge((node[0],node[1],Orientation.up), (node[0]+1,node[1],Orientation.up))
			if ws[1] == 0:
				graph.add_edge((node[0],node[1],Orientation.left), (node[0],node[1]-1,Orientation.left))
			if ws[2] == 0:
				graph.add_edge((node[0],node[1],Orientation.down), (node[0]-1,node[1],Orientation.down))
			if ws[3] == 0:
				graph.add_edge((node[0],node[1],Orientation.right), (node[0],node[1]+1,Orientation.right))

		return graph
示例#37
0
class TestUndirectedGraphMethods(unittest.TestCase):
    def setUp(self):
        self.graph = UndirectedGraph()
        self.filled_graph = UndirectedGraph()

        for i in range(6):
            self.filled_graph.add_vertex(i + 1)

        self.filled_graph.add_edge(1, 2)
        self.filled_graph.add_edge(1, 4)
        self.filled_graph.add_edge(2, 4)
        self.filled_graph.add_edge(2, 3)
        self.filled_graph.add_edge(4, 3)
        self.filled_graph.add_edge(3, 6)
        self.filled_graph.add_edge(4, 5)
        self.filled_graph.add_edge(5, 6)

    def test_adjacent(self):
        # Edge does exist.
        self.assertTrue(self.filled_graph.adjacent(1, 2))

        # Edge does not exist.
        self.assertFalse(self.filled_graph.adjacent(1, 3))

        # Vertices to test do not exist.
        self.assertFalse(self.filled_graph.adjacent(5, 8))

    def test_neighbors(self):
        self.assertCountEqual(self.filled_graph.neighbors(4), [1, 2, 3, 5])
        self.assertCountEqual(self.filled_graph.neighbors(6), [3, 5])
        self.assertEqual(self.filled_graph.neighbors(199), [])

    def test_add_vertex(self):
        old_len = len(self.graph)
        self.graph.add_vertex(0)
        self.assertEqual(len(self.graph), old_len + 1)

    def test_remove_vertex(self):
        # Remove a vertex that exists and verify its neighbors are updated.
        target = 6
        old_len = len(self.filled_graph)
        self.filled_graph.remove_vertex(target)

        self.assertEqual(len(self.filled_graph), old_len - 1)
        self.assertNotIn(target, self.filled_graph.vertices)
        self.assertNotIn(target, self.filled_graph.neighbors(3))
        self.assertNotIn(target, self.filled_graph.neighbors(5))

        # Attempt to remove a vertex that doesn't exist.
        target = 100
        old_len = len(self.filled_graph)
        self.filled_graph.remove_vertex(target)
        self.assertEqual(len(self.filled_graph), old_len)
        self.assertNotIn(target, self.filled_graph.vertices)

    def test_add_edge(self):
        # Add edge between existing vertices.
        self.assertFalse(self.filled_graph.adjacent(2, 6))
        self.filled_graph.add_edge(2, 6)
        self.assertTrue(self.filled_graph.adjacent(2, 6))

        # Attempt to add edge to vertex that doesn't exist.
        self.filled_graph.add_edge(2, 100)
        self.assertNotIn(100, self.filled_graph.neighbors(2))

    def test_remove_edge(self):
        # Remove existing edge.
        self.assertIn(3, self.filled_graph.neighbors(6))
        self.filled_graph.remove_edge(3, 6)
        self.assertNotIn(3, self.filled_graph.neighbors(6))

        # Attempt to remove non-existing edge.
        self.assertNotIn(1, self.filled_graph.neighbors(5))
        self.filled_graph.remove_edge(1, 5)
        self.assertNotIn(1, self.filled_graph.neighbors(5))