Re: Conversion to graph adjacency list

Jason Sachs <[email protected]>
Newsgroups gmane.comp.python.scientific.user
Message-ID <CAOo6sOMkDhnc+S9fb4042dvGvN5yBZbegmkZyHxq57yopRo=hA@mail.gmail.com>
Hmm. I'm not an expert here, but did you try using the "networkx" package?

On Sat, Dec 8, 2018 at 7:36 AM <[email protected]> wrote:

>
> Thanks Robert for your hepfull response, now I better understand how csr
> conversion works.
>
> I'm benchmarking some graph libraries. My edges-to-csr conversion was
> hand-written in Python, so very slow! Now, with your code, execution time
> is 7 times faster!
>
> Here is the code, perhaps we can optimize more:
>
>
> # =============================================
> from time import clock
> from sys import stderr, stdin
>
> from scipy.sparse.csgraph import minimum_spanning_tree
> from scipy.sparse import csr_matrix
> import numpy as np
>
>
> # ------------ Scipy Code ---------------------------
>
> def wedges2adj(edges, n):
>
>     G=[[]for _ in range(n)]
>     for a, b, w in edges:
>         G[a].append((b,w))
>         G[b].append((a,w))
>     return G
>
> def wedges2scr(edges, n):
>     G=wedges2adj(edges, n)
>     indptr=[0]
>     cnt=0
>
>     for line in G:
>         cnt+=len(line)
>         indptr.append(cnt)
>     data=[]
>     indices=[]
>     for i in range(n):
>         for (j,w) in G[i]:
>             data.append(w)
>             indices.append(j)
>
>     return [data, indptr, indices]
>
> def csr2wedges(Mcsr, shape):
>     n, p=shape
>     k=0
>     edges=[]
>     data, cumul, cols  = Mcsr.data,Mcsr.indptr, Mcsr.indices
>     for i in range(n):
>         for j in range(cumul[i+1]-cumul[i]):
>             edges.append((i, cols[k], data[k]))
>             k+=1
>     return edges
>
> def kruskal_scipy(edges, n):
>     data, indptr, indices=wedges2scr(edges, n)
>     csr=csr_matrix((data, indices, indptr), shape=(n, n))
>     tree=minimum_spanning_tree(csr)
>     edges=csr2wedges(tree, (n,n))
>     return int(sum((round(w)) for (a,b,w) in edges))
>
> # °°°°°°°°°°°°°°°°°°°°°°°
>
>
>
> def wedges2scr_FAST(wedges, n):
>     row_ind, col_ind, costs = np.transpose(wedges)
>     return csr_matrix((costs, (row_ind, col_ind)),
>     shape=(n,n))
>
> def kruskal_scipy_FAST(wedges, n):
>     csr=wedges2scr_FAST(wedges, n)
>     tree=minimum_spanning_tree(csr).tocoo()
>     return int(round(sum(w for (i,j,w) in zip(tree.row, tree.col,
> tree.data))))
>
>
> # ------------ Benchmark ---------------------------
>
> def go(solver, L):
>     global duration
>
>     N=len(L)
>     k=1
>     solution=[]
>     while k<N:
>         edges=[]
>         n=L[k]
>         k+=1
>
>         for a in range(n):
>             d=L[k]
>             k+=1
>             for j in range(d):
>                 b=L[k]
>                 k+=1
>                 w=L[k]
>                 k+=1
>                 if a<b:
>                     edges.append([a,b-1,w])
>         if solver==kruskal_scipy:
>             data, indptr, indices=wedges2scr(edges, n)
>
>             start=clock()
>             csr=csr_matrix((data, indices, indptr), shape=(n, n))
>
>             tree=minimum_spanning_tree(csr)
>             edges=csr2wedges(tree, (n,n))
>             sol=solver(edges, n)
>             duration+=clock()-start
>             solution.append(sol)
>         else:
>
>             start=clock()
>             sol=solver(edges, n)
>             duration+=clock()-start
>             solution.append(sol)
>     return solution
>
> # data
> L=list(int(z) for z in stdin.read().split() if z.isdigit())
> output=[]
> solvers=[kruskal_scipy, kruskal_scipy_FAST]
> for solver in solvers:
>     duration=0
>     costs=go(solver, L)
>     output.append(costs)
>     print("%-20s : %.3f" %(solver.__name__, duration), file=stderr)
>
> if all(output[i]== output[0] for i in range(len(solvers))):
>     print("NO error detected", file=stderr)
> else:
>     print("ERROR detected", file=stderr)
>
> # =============================================
>
>
> Link to data file (100 graphs with at most 30000 vertices each):
>
>
> https://drive.google.com/file/d/1BKxRAzJ9jeowbrFPyLZ23EomKn1eqohs/view?usp=sharing
>
> The above code is faster than Networkit library code and little slower
> than Graph-Tool library.
>
> I have two observations:
>
> 1. Python code is only 2 times slower
> 2. Pure C-code is about 9 times faster
>
> In each case, even SciPy cf. _min_spanning_tree.pyx, algorithm is the
> same: kruskal with Union-find.
>
>
>
>
> _______________________________________________
> SciPy-User mailing list
> [email protected]
> https://mail.python.org/mailman/listinfo/scipy-user
>

_______________________________________________
SciPy-User mailing list
[email protected]
https://mail.python.org/mailman/listinfo/scipy-user
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.