Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.43 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: iso-8859-15 -*-
  3. """
  4. ReTrace - find branching pathways in metabolic networks
  5. Copyright (C) 2009 Esa Pitkдnen
  6. See file COPYING for license notice.
  7.  
  8. Implementation of Yen's k shortest simple (loopless) paths.
  9.  
  10. Running time is O(kn(m + n log n)) in a graph with n nodes
  11. and m edges.
  12.  
  13. """
  14.  
  15. #try:
  16. #    import psyco # try to enable psyco JIT
  17. #    psyco.full()
  18. #except:
  19. #    pass
  20.  
  21. import sys, os, random, time, math
  22.  
  23. from graph import randomGraph, graphGenerators, graph
  24. from eppstein import dijkstra, priodict
  25.  
  26. class Path(list):
  27.     def __hash__(self):
  28.         h = ""
  29.         for e in self.__iter__():
  30.             h += "%s*" % (e)
  31.         return hash(h)
  32.  
  33. def getPath(s, t, P, G):
  34.     cost = 0.0
  35.     n = t
  36.     p = Path()
  37.  
  38.     if len(P) == 0 or t not in P:
  39.         return p, 0
  40.  
  41.     while n != s:
  42.         cost += G.E[P[n]][n]
  43.         p.append(n)
  44.         n = P[n]
  45.     p.append(n)
  46.     p.reverse()
  47.     return p, cost
  48. import heapq
  49. def kspSimpleYen(G, K, s, t):
  50.     assert(K > 0)
  51.     X = priodict.priorityDictionary()  # paths
  52.     X = []
  53.     removals = {}
  54.    
  55.     found = set()
  56.     pathways = []
  57.  
  58.     (D, P) = dijkstra.Dijkstra(G.E, s, t)
  59.     p, cost = getPath(s, t, P, G)
  60.     p.cost = cost
  61.     p.dix = 0
  62.     #X[p] = cost
  63.     heapq.heappush(X,(p,cost))
  64.     removals[p] = []
  65.     found.add(p)
  66.  
  67.     k = 0
  68.     I = 0
  69.     #for p in X:
  70.     while X:
  71.         p, _cost = heapq.heappop(X)
  72.         R = removals.pop(p)
  73.  
  74.         pathways.append(p)
  75.  
  76.         k += 1
  77.         if k == K:
  78.             break
  79.  
  80.         # Add to removals every edge from nodes v_{l-1}, l = |p|
  81.         # on the path p, starting from the end of the path
  82.  
  83.         for (u, v, c) in R:
  84.             del G.E[u][v]
  85.  
  86.         R2 = []
  87.         i = p.dix
  88.         while i < len(p) - 1:
  89.             I += 1
  90.             # Delete the next edge on the path
  91.             pi = p[i]
  92.             pii = p[i + 1]
  93.             R2.append((pi, pii, G.E[pi][pii]))
  94.             del G.E[pi][pii]
  95.  
  96.             (D, P) = dijkstra.Dijkstra(G.E, pi, t)
  97.             p2, cost = getPath(pi, t, P, G)
  98.  
  99.             if len(p2) > 0:
  100.                 p3 = Path(p[0:i])
  101.                 p3.extend(p2)
  102.  
  103.                 if p3 not in found:
  104.                     p3.cost = p.cost + cost
  105.                     p3.dix = i
  106.                     X[p3] = p3.cost
  107.                     removals[p3] = list(R2)
  108.                     found.add(p3)
  109.  
  110.             R3 = []
  111.             for u in G.E[pi]:
  112.                 if u != pii:
  113.                     R3.append((pi, u, G.E[pi][u]))
  114.  
  115.             for (u, v, c) in R3:
  116.                 del G.E[u][v]
  117.             R2.extend(R3)
  118.             i += 1
  119.  
  120.         # Restore graph
  121.  
  122.         for (u, v, c) in R2:
  123.             G.E[u][v] = c
  124.  
  125.         for (u, v, c) in R:
  126.             G.E[u][v] = c
  127.  
  128.     print 'I =',I    
  129.     return pathways
  130.  
  131. def testKSP():
  132.     G = graphGenerators.martinsPascoalExample()
  133.     s = "N1"
  134.     t = "N5"
  135.     P = kspSimpleYen(G, 100, s, t)
  136.     for p in P:
  137.         print p
  138.  
  139. def meansd(L):
  140.     mean = 1.0 * reduce(lambda x, y: x + y, L) / len(L)
  141.     sum = 0.0
  142.     for x in L:
  143.         sum += (x - mean) * (x - mean)
  144.     sd = math.sqrt(sum / len(L))
  145.     return mean, sd
  146.  
  147.  
  148. def testKSP2():
  149.     edgetonoderatio = 1.5
  150.  
  151.     krange = range(50, 55, 5)
  152.     nrange = range(200, 1000, 10)
  153.     rounds = 1
  154.     rrange = range(rounds)
  155.  
  156.     o = sys.stdout
  157.  
  158.     s = 1
  159.     t = 2
  160.    
  161.     o.flush()
  162.     for k in krange:
  163.         for n in nrange:
  164.  
  165.             o.write("%d\t%d\t" % (k, rounds))
  166.             o.flush()
  167.             m = int(edgetonoderatio * n)
  168.             G = randomGraph.randomGraph(n, m)
  169.             o.write("%d\t%d\t" % (G.numNodes(), G.numEdges()))
  170.             o.flush()
  171.             times = []
  172.  
  173.             for r in rrange:
  174.                 V = list(G.V)
  175.                 s = random.choice(V)
  176.                 t = random.choice(V)
  177.  
  178.                 st = time.time()
  179.  
  180.                 paths = kspSimpleYen(G, k, s, t)
  181.  
  182.                 et = time.time()
  183.  
  184.                 times.append(et - st)
  185.  
  186.             mean, sd = meansd(times)
  187.             o.write("%f\t%f\t%d\n" % (mean, sd, len(paths)))
  188.             o.flush()
  189.  
  190. def removeCyclicPaths(P):
  191.     Q = []
  192.     for p in P:
  193.         nodes = set()
  194.         cyclic = False
  195.         for n in p:
  196.             if n in nodes:
  197.                 cyclic = True
  198.                 break
  199.             else:
  200.                 nodes.add(n)
  201.         if not cyclic:
  202.             Q.append(p)
  203.     return Q
  204.  
  205.  
  206. G =  {0: {1: 4, 4: 4, 5: 254, },
  207. 1: {2: 4, 4: 254, 5: 4, },
  208. 2: {3: 4, 5: 254, 6: 5, 7: 254, },
  209. 3: {6: 254, 7: 6, },
  210. 4: {5: 4, 8: 4, 9: 254, },
  211. 5: {6: 4, 8: 254, 9: 4, },
  212. 6: {7: 4, 9: 254, 10: 4, },
  213. 7: {11: 5, },
  214. 8: {9: 4, 12: 4, 13: 254, },
  215. 9: {10: 4, 12: 254, 13: 4, },
  216. 10: {11: 4, 13: 254, },
  217. 11: {15: 5, },
  218. 12: {13: 4, },
  219. 13: {},
  220. 15: {},
  221. }
  222. def cost(G, p):
  223.     return sum([G1[x[0]][x[1]] for x in zip(p,p[1:])])
  224. def triangular2usual(G):
  225.    G1={}
  226.    for v1 in G.iterkeys():
  227.       for (v2, cost2) in G[v1].iteritems():
  228.          if not G1.has_key(v1): G1[v1]={}
  229.          if not G1.has_key(v2): G1[v2]={}
  230.          G1[v1][v2]=cost2
  231.          G1[v2][v1]=cost2
  232.    return G1
  233. import itertools
  234. def path_overlay(p):
  235.    allp = set(reduce(lambda x, y: x+y, p))
  236.    cnt = 0.0;
  237.    for v in allp:
  238.       for pp in p:
  239.          if pp.count(v): cnt += 1
  240.    return cnt/len(allp)
  241.  
  242. def overlays(G, paths, n):
  243.    for pp in paths:
  244.       #pp = [int(x) for x in p.split(',')]      
  245.       s=0
  246.       for v in range(len(pp)-1):
  247.          s += G[pp[v]][pp[v+1]]      
  248.       print pp,s  
  249.    l_overlay = [(path_overlay(c),sum([cost(G,p) for p in c]),c) for c in itertools.combinations(paths,n)]
  250.    m1,m2 = max([x[0] for x in l_overlay]), float(max([x[1] for x in l_overlay]))
  251.    l_overlay = [(x[0]/m1, x[1]/m2, x[2]) for x in l_overlay]
  252.    l_overlay.sort(lambda x,y: cmp(x[0]**2+x[1]**2,y[0]**2+y[1]**2))
  253.    print 'paths:', len(paths)
  254.    print 'overlays:(',len(l_overlay),')', l_overlay[0]
  255.  
  256. if __name__ == "__main__":
  257.     #testKSP2()
  258.     G1 = triangular2usual(G)
  259.     G2 = graph.Graph()
  260.     for v1 in G1:
  261.         G2.addNode(v1)
  262.     for v1 in G1:        
  263.         for v2 in G1[v1]:
  264.             G2.addEdge(v1,v2,G1[v1][v2])
  265.     paths = kspSimpleYen(G2,20,0,15)
  266.     sp = []
  267.     for p in paths:
  268.         vp = zip(p,p[1:])
  269.         s = cost(G,p)
  270.         sp.append((s,tuple(p)))
  271.     #sp.sort(lambda x,y: cmp(x[0],y[0]))
  272.     for _sp in sp:
  273.         print _sp
  274.     overlays(G1,paths,4)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement