示例#1
0
 def test_topo_order(self):
     g = DiGraph(4)
     g.add_edge(0, 1)
     g.add_edge(0, 2)
     g.add_edge(1, 3)
     g.add_edge(2, 3)
     self.assertFalse(HamiltonPathDag(g).has_hamilton_path)
示例#2
0
def from_networkx(G):
    """
	Convert a NetworkX graph into a Zen graph object.
	
	In creating the object, the NetworkX node object and node/edge data will be copied over (a shallow copy).
	
	**Returns**:
		The return type depends on the input type.
		
		* :py:class:`zen.Graph` if the input graph was a :py:class:`networkx.Graph`.
		* :py:class:`zen.DiGraph` if the input graph was a :py:class:`networkx.DiGraph`.
	"""
    Gdest = None
    if type(G) == networkx.DiGraph:
        Gdest = DiGraph()
    elif type(G) == networkx.Graph:
        Gdest = Graph()
    else:
        raise Exception, 'Unable to convert graph object type %s' % str(
            type(G))

    # add nodes
    for n, nd in G.nodes_iter(data=True):
        Gdest.add_node(n, nd)

    # add edges
    for x, y, ed in G.edges_iter(data=True):
        Gdest.add_edge(x, y, ed)

    return Gdest
示例#3
0
文件: nx.py 项目: buguen/zenlib
def from_networkx(G):
	"""
	Convert a NetworkX graph into a Zen graph object.
	
	In creating the object, the NetworkX node object and node/edge data will be copied over (a shallow copy).
	
	**Returns**:
		The return type depends on the input type.
		
		* :py:class:`zen.Graph` if the input graph was a :py:class:`networkx.Graph`.
		* :py:class:`zen.DiGraph` if the input graph was a :py:class:`networkx.DiGraph`.
	"""
	Gdest = None
	if type(G) == networkx.DiGraph:
		Gdest = DiGraph()
	elif type(G) == networkx.Graph:
		Gdest = Graph()
	else:
		raise Exception, 'Unable to convert graph object type %s' % str(type(G))
	
	# add nodes	
	for n,nd in G.nodes_iter(data=True):
		Gdest.add_node(n,nd)
		
	# add edges
	for x,y,ed in G.edges_iter(data=True):
		Gdest.add_edge(x,y,ed)
		
	return Gdest
class WordLadder:
    # Create a graph from the file of four letter words
    def __init__(self, filename):
        self.word_graph = DiGraph()
        # Use with for opening file
        with open(filename) as file:
            d = defaultdict(list)
            for line in file:
                word = line.strip().lower()  # Get the word
                # add 'word' in '_ord', 'w_rd', 'wo_d' and 'wor_'
                for i in range(4):  # we know its 4 letter words
                    temp = word[:i] + '_' + word[i+1:]
                    d[temp].append(word)

            # from dictionary, make graph
            for l in d.values():  # For each dictionary list,
                # add edge between all nodes
                # in 'wor_', 'work' and 'word' are neighbours
                for frm in range(len(l)):
                    for to in range(len(l)):
                        if frm != to:
                            self.word_graph.add_edge(l[frm], l[to])

    @staticmethod
    def print_path(previous, from_word, to_word):
        l = []

        node_id = to_word
        while node_id != from_word:
            l.append(node_id)
            node_id = previous[node_id]

        l.append(from_word)

        print(l[::-1])

    def find_path(self, from_word, to_word):
        if from_word == to_word:
            return

        q = Queue()  # q for BFS
        previous = {}  # Previous to store predecessor nodes

        q.put(from_word)  # add the start node to q
        previous[from_word] = None

        while not q.empty():
            node_id = q.get()
            start = self.word_graph.vert_list[node_id]

            for neigh in start.get_neighs():
                if neigh in previous:  # If neighbour is visited, continue
                    continue
                previous[neigh] = node_id
                if neigh == to_word:  # Found a path
                    self.print_path(previous, from_word, to_word)
                    return
                q.put(neigh)  # add neighbours to q
        # end of graph traversal
        print('No Path')
示例#5
0
def test_destination_is_not_reachable_if_path_does_not_exists():
    dg = DiGraph()
    dg.add_nodes_from([1, 2, 3, 4, 5])
    dg.add_edge(1, 2)
    dg.add_edge(2, 3)
    dg.add_edge(3, 4)

    assert not is_reachable(dg, 1, 5)
示例#6
0
def test_get_path_returns_path_when_path_exists():
    dg = DiGraph()
    dg.add_nodes_from([1, 2, 3, 4, 5])
    dg.add_edge(1, 2)
    dg.add_edge(2, 3)
    dg.add_edge(3, 4)
    dg.add_edge(4, 2)

    assert get_path(dg, 1, 4) == [1, 2, 3, 4]
示例#7
0
文件: test_bfs.py 项目: gj1292/Plexus
def test_bfs_on_directed_graph():
    dg = DiGraph()
    dg.add_nodes_from([1, 2, 3, 4, 5])
    dg.add_edge(1, 2)
    dg.add_edge(1, 3)
    dg.add_edge(2, 4)
    dg.add_edge(3, 4)

    assert bfs(dg, 1) == [1, 2, 3, 4]
示例#8
0
def test_get_path_raises_path_not_found_error_if_no_path_exists():
    dg = DiGraph()
    dg.add_nodes_from([1, 2, 3, 4, 5])
    dg.add_edge(1, 2)
    dg.add_edge(2, 3)
    dg.add_edge(3, 4)
    dg.add_edge(4, 2)

    with pytest.raises(PathNotFoundError):
        get_path(dg, 1, 5)
class StronglyConnectedComponent:
    def __init__(self, g):
        self.g = g
        self.rg = None
        self.done = [False]*self.g.V
        self.topo_order = []
        self.cc_count = 0
        self.cc_id = [-1]*self.g.V       #Valid id are positive integeres starting from 1
        self.generate_reverse_graph()
        self.populate_topo_order()
        self.populate_strongly_cc()

    def populate_topo_order(self):
        for i in range(self.rg.V):
            if not self.done[i]:
                self.topo_util(i)

    def get_reverse_topo_order(self):
        return list(reversed(self.topo_order))
                
    def topo_util(self, v):
        self.done[v] = True
        for each in self.rg.adj(v):
            if not self.done[each]:
                self.topo_util(each)
        self.topo_order.append(v)
        
    def generate_reverse_graph(self):
        self.rg = DiGraph(self.g.V)
        for i in range(self.rg.V):
            for j in self.g.adj(i):
                self.rg.add_edge(j, i)
    
    def populate_strongly_cc(self):
        self.done = [False]*self.g.V
        for each in self.get_reverse_topo_order():
            if not self.done[each]:
                self.cc_count += 1
                self.cc_dfs(each)

    def cc_dfs(self, v):
        self.done[v] = True
        self.cc_id[v] = self.cc_count
        for each in self.g.adj(v):
            if not self.done[each]:
                self.cc_dfs(each) 

    def get_component_count(self):
        return self.cc_count

    def get_component_id(self, v):
        return self.cc_id[v]    

    def are_strongly_connected(self, v, w):
        return self.get_component_id(v) == self.get_component_id(w)
 def test_length1(self):
     g = DiGraph(7)
     g.add_edge(0, 1)
     g.add_edge(0, 2)
     g.add_edge(1, 3)
     g.add_edge(3, 4)
     g.add_edge(3, 6)
     g.add_edge(6, 3)
     g.add_edge(4, 5)
     g.add_edge(5, 3)
     g.add_edge(5, 0)
     l = SmallestCycle(g).get_smallest_cycle_length()
     self.assertEqual(l, 2)
 def test_strongly_connected(self):
     g = DiGraph(6)
     g.add_edge(0, 1)
     g.add_edge(1, 2)
     g.add_edge(2, 0)
     g.add_edge(2, 3)
     g.add_edge(3, 4)
     g.add_edge(4, 3)
     g.add_edge(5, 3)
     self.assertTrue(DigraphHasReachableVertex(g).has_rechable_vertex())
 def test_component_count(self):
     g = DiGraph(6)
     g.add_edge(0, 1)
     g.add_edge(0, 2)
     g.add_edge(2, 3)
     g.add_edge(3, 0)
     g.add_edge(2, 4)
     g.add_edge(4, 5)
     g.add_edge(5, 4)
     self.assertFalse(DigraphHasReachableVertex(g).has_rechable_vertex())        
 def test_component_count(self):
     g = DiGraph(6)
     g.add_edge(0, 1)
     g.add_edge(0, 2)
     g.add_edge(2, 3)
     g.add_edge(3, 0)
     g.add_edge(2, 4)
     g.add_edge(4, 5)
     g.add_edge(5, 4)
     self.assertEqual(StronglyConnectedComponent(g).get_component_count(), 3)        
示例#14
0
 def test_does_not_exists(self):
     g = DiGraph(8)
     g.add_edge(0, 5)
     g.add_edge(0, 4)
     g.add_edge(6, 5)
     g.add_edge(7, 5)
     g.add_edge(3, 1)
     g.add_edge(1, 0)
     g.add_edge(4, 6)
     v = ReachableVertexDAG(g).get_reachable_vertex()
     self.assertEqual(v, None)
 def test_topo_order(self):
     g = DiGraph(6)
     g.add_edge(0, 1)
     g.add_edge(0, 2)
     g.add_edge(2, 3)
     g.add_edge(3, 0)
     g.add_edge(2, 4)
     g.add_edge(4, 5)
     g.add_edge(5, 4)
     rto = DigraphHasReachableVertex(g).get_reverse_topo_order()
     self.assertListEqual(rto, [4, 5, 1, 0, 3, 2])        
 def test_topo_order(self):
     g = DiGraph(6)
     g.add_edge(0, 1)
     g.add_edge(0, 2)
     g.add_edge(2, 3)
     g.add_edge(3, 0)
     g.add_edge(2, 4)
     g.add_edge(4, 5)
     g.add_edge(5, 4)
     rto = StronglyConnectedComponent(g).get_reverse_topo_order()
     self.assertListEqual(rto, [4, 5, 1, 0, 3, 2])        
 def test_strongly_connected(self):
     g = DiGraph(6)
     g.add_edge(0, 1)
     g.add_edge(0, 2)
     g.add_edge(2, 3)
     g.add_edge(3, 0)
     g.add_edge(2, 4)
     g.add_edge(4, 5)
     g.add_edge(5, 4)
     self.assertTrue(StronglyConnectedComponent(g).are_strongly_connected(0, 2))        
     self.assertTrue(StronglyConnectedComponent(g).are_strongly_connected(3, 2))        
     self.assertTrue(StronglyConnectedComponent(g).are_strongly_connected(4, 5))        
     self.assertFalse(StronglyConnectedComponent(g).are_strongly_connected(4, 2))        
示例#18
0
文件: nx.py 项目: dellsystem/zenlib
def from_networkx(G):
	"""
	This function converts a graph from a networkx data structure into a Zen graph.
	"""
	Gdest = None
	if type(G) == networkx.DiGraph:
		Gdest = DiGraph()
	elif type(G) == networkx.Graph:
		Gdest = Graph()
	else:
		raise Exception, 'Unable to convert graph object type %s' % str(type(G))
	
	# add nodes	
	for n,nd in G.nodes_iter(data=True):
		Gdest.add_node(n,nd)
		
	# add edges
	for x,y,ed in G.edges_iter(data=True):
		Gdest.add_edge(x,y,ed)
		
	return Gdest
示例#19
0
 def test_topo_order(self):
     g = DiGraph(6)
     g.add_edge(2, 1)
     g.add_edge(1, 0)
     g.add_edge(0, 4)
     g.add_edge(4, 3)
     g.add_edge(3, 5)
     self.assertTrue(HamiltonPathDag(g).has_hamilton_path)
 def test_no_cycle(self):
     g = DiGraph(7)
     g.add_edge(0, 1)
     g.add_edge(0, 2)
     g.add_edge(1, 3)
     g.add_edge(3, 4)
     g.add_edge(4, 5)
     l = SmallestCycle(g).get_smallest_cycle_length()
     self.assertEqual(l, None)
示例#21
0
    # we need 3 flags (0, 1, 2) to check if there is a cycle.
    # 0=not visited, 1=in the process, 2=visited
    for node in g.get_vertices():
        visited[node] = 0

    # Go through each non-visited node and start a DFS from that node
    for node in g.get_vertices():
        if visited[node] != 2:
            depth_traversal(g, node, visited, topology)

    # Reverse the topology and print
    print(topology[::-1])
    return topology[::-1]

if __name__ == '__main__':
    g = DiGraph()
    g.add_edge(6, 3)
    g.add_edge(3, 7)
    g.add_edge(3, 2)
    g.add_edge(1, 2)
    g.add_edge(10, 1)
    # g.add_edge(2, 8)
    # g.add_edge(5, 9)
    # g.add_edge(5, 4)
    # g.add_edge(4, 8)
    # g.add_edge(8, 6)
    try:
        topological_sort(g)
    except CycleException:
        print('Graph contains Cycle')
                maxim_path = m_path.copy()  # NBNBNBNB: Do a copy().
            path.pop()
            visited.remove(neigh)
    return maxim, maxim_path  # If not connected, return (0, [])


def maximum_cost_path(g, start, end):  # COPIED
    visited = set()
    visited.add(start)
    path = [start]
    return _maximum_cost_path(g, start, end, visited, path, 0)


if __name__ == '__main__':
    g = DiGraph()
    g.add_edge(0, 1)
    g.add_edge(0, 6)
    g.add_edge(1, 2)
    g.add_edge(1, 5)
    g.add_edge(1, 6)
    g.add_edge(2, 3)
    g.add_edge(3, 4)
    g.add_edge(5, 2)
    g.add_edge(5, 3)
    g.add_edge(5, 4)
    g.add_edge(6, 5)
    g.add_edge(7, 1)
    g.add_edge(7, 6)
    print(count_paths(g, 1, 5))
    print(paths_with_m_edges(g, 0, 3, 4))
    print('***')
    return False


def cycle_undirected(g):
    visited = [False] * (g.num_vert + 1)

    for node in g:  # loop through all the nodes
        if visited[node.key] != True:
            if cycle_dfs_u(g, node.key, visited, -1):
                return True
    print('No cycle')


if __name__ == '__main__':
    g = DiGraph()
    g.add_edge(3, 2)
    g.add_edge(4, 5)
    g.add_edge(5, 2)
    g.add_edge(5, 3)
    g.add_edge(3, 1)
    g.add_edge(6, 5)
    # cycle_directed(g)

    g = NGraph()
    g.add_edge(1, 5)
    g.add_edge(4, 5)
    g.add_edge(4, 6)
    g.add_edge(3, 6)
    g.add_edge(3, 2)
    g.add_edge(2, 6)
    cycle_undirected(g)
class DigraphHasReachableVertex:
    def __init__(self, g):
        self.g = g
        self.rg = None
        self.done = [False]*self.g.V
        self.topo_order = []
        self.cc_count = 0
        self.cc_id = [-1]*self.g.V       #Valid id are positive integeres starting from 1
        self.generate_reverse_graph()
        self.populate_topo_order()
        self.cc_dag = DiGraph(0)
        self.populate_strongly_cc_dag()

    def populate_topo_order(self):
        for i in range(self.rg.V):
            if not self.done[i]:
                self.topo_util(i, self.rg)

    def get_reverse_topo_order(self):
        return list(reversed(self.topo_order))
                
    def topo_util(self, v, g):
        self.done[v] = True
        for each in g.adj(v):
            if not self.done[each]:
                self.topo_util(each, g)
        self.topo_order.append(v)
        
    def generate_reverse_graph(self):
        self.rg = DiGraph(self.g.V)
        for i in range(self.rg.V):
            for j in self.g.adj(i):
                self.rg.add_edge(j, i)
    
    def populate_strongly_cc_dag(self):
        self.done = [False]*self.g.V
        for each in self.get_reverse_topo_order():
            if not self.done[each]:
                self.cc_count += 1
                self.cc_dag.add_vertex()
                self.cc_dfs(each)

    def cc_dfs(self, v):
        self.done[v] = True
        self.cc_id[v] = self.cc_count-1
        for each in self.g.adj(v):
            if self.done[each] and self.cc_id[each] != self.cc_id[v]:
                self.cc_dag.add_edge(self.cc_count-1, self.cc_id[each])
            if not self.done[each]:
                self.cc_dfs(each) 

    def has_rechable_vertex(self):
        zero_degree_count = 0
        for i in range(self.cc_dag.V):
            if len(self.cc_dag.adj(i))==0:
                zero_degree_count += 1
                if zero_degree_count > 1:
                    return False
        if zero_degree_count == 0:
            return False
        return True
class KnightsTour:
    def __init__(self, row, column):
        self.board = DiGraph()  # Directed graph
        self.row = row
        self.column = column

        for r in range(row):
            for c in range(column):
                pos = (r * column) + c
                # For each position, find the valid moves and add as edges
                for neigh in self.get_neighs(r, c):
                    self.board.add_edge(pos, neigh)

    def get_neighs(self, row, column):
        # For each position, there can be up to 8 valid moves
        moves = [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2),
                 (2, -1), (2, 1)]
        ret = []

        for x, y in moves:
            n_row = row + x
            n_clm = column + y
            # If a valid move, add it to return list
            if 0 <= n_row < self.row and 0 <= n_clm < self.column:
                neigh = n_row * self.column + n_clm
                ret.append(neigh)

        return ret

    def order_by_avail(self, start, visited):
        ret = []

        node = self.board.vert_list[start]
        for neigh in node.get_neighs():
            if neigh in visited:
                continue
            c = 0
            for next in self.board.vert_list[neigh].get_neighs():
                if next not in visited:
                    c += 1
            #  Out of for loop. C can be 0 also. Still need to include in ret
            ret.append((neigh, c))

        # wrong because ret.sort return None
        # return [y[0] for y in ret.sort(key=lambda x:x[1])]
        return [y[0] for y in sorted(ret, key=lambda x: x[1])]

    def solve(self, start):
        visited = set()
        path = []  # passing of path technique happens with DFS
        return self._solve(start, path, visited)

    def _solve(self, start, path, visited):
        path.append(start)
        visited.add(start)  # mark this node as visited
        if len(visited) == self.board.num_vert:  # Visited all nodes
            print(path)
            return 1

        count = 0
        # for neigh in node.get_neighs():
        for neigh in self.order_by_avail(start, visited):
            if neigh in visited:  # neigh may get visited after getting it as list in order_by_avail
                continue
            count += self._solve(neigh, path, visited)
            # if self._solve(neigh, path, visited): # solve using neigh
            # If solved, Done
            #     return True

        # Done with start. No path found through it.
        visited.remove(start)
        path.pop()
        return count