how to create random single source random acyclic directed graphs with negative edge weights in python

杀马特。学长 韩版系。学妹 提交于 2019-12-06 07:42:16

问题


I want to do a execution time analysis of the bellman ford algorithm on a large number of graphs and in order to do that I need to generate a large number of random DAGS with the possibility of having negative edge weights.

I am using networkx in python. There are a lot of random graph generators in the networkx library but what will be the one that will return the directed graph with edge weights and the source vertex.

I am using networkx.generators.directed.gnc_graph() but that does not quite guarantee to return only a single source vertex.

Is there a way to do this with or even without networkx?


回答1:


I noticed that the generated graphs have always exactly one sink vertex which is the first vertex. You can reverse direction of all edges to get a graph with single source vertex.




回答2:


You can generate random DAGs using the gnp_random_graph() generator and only keeping edges that point from lower indices to higher. e.g.

In [44]: import networkx as nx

In [45]: import random

In [46]: G=nx.gnp_random_graph(10,0.5,directed=True)

In [47]: DAG = nx.DiGraph([(u,v,{'weight':random.randint(-10,10)}) for (u,v) in G.edges() if u<v])

In [48]: nx.is_directed_acyclic_graph(DAG)
Out[48]: True

These can have more than one source but you could fix that with @Christopher's suggestion of making a "super source" that points to all of the sources.

For small connectivity probability values (p=0.5 in the above) these won't likely be connected either.




回答3:


The method suggested by @Aric will generate random DAGs but the method will not work for a large number of nodes for example: for n tending to 100000.

        G = nx.gnp_random_graph(n, 0.5, directed=True)
        DAG = nx.DiGraph([(u, v,) for (u, v) in G.edges() if u < v])
        # print(nx.is_directed_acyclic_graph(DAG)) # to check if the graph is DAG (though it will be a DAG)
        A = nx.adjacency_matrix(DAG)
        AM = A.toarray().tolist()  # 1 for outgoing edges
        while(len(AM)!=n):
            AM = create_random_dag(n)

        # to display the DAG in matplotlib uncomment these 2 line
        # nx.draw(DAG,with_labels = True)
        # plt.show()

        return AM

For a large number of nodes, you can use the property that every lower triangular matrix is a DAG. So generating random Lower Triangular matrix will generate random DAG.

        mat = [[0 for x in range(N)] for y in range(N)]
        for _ in range(N):
             for j in range(5):
                 v1 = random.randint(0,N-1)
                 v2 = random.randint(0,N-1)
                 if(v1 > v2):
                     mat[v1][v2] = 1
                 elif(v1 < v2):
                     mat[v2][v1] = 1

        for r in mat:
            print(','.join(map(str, r)))


来源:https://stackoverflow.com/questions/13543069/how-to-create-random-single-source-random-acyclic-directed-graphs-with-negative

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!