Advertisement
Guest User

Untitled

a guest
Feb 26th, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.38 KB | None | 0 0
  1. #!/usr/bin/env python
  2. #encoding: utf-8
  3. import random
  4. import argparse
  5. import pstats
  6. import cProfile
  7. import sys
  8. sys.path.append("C:\\Users\\Utente\\Downloads")
  9. from sorting.sorting.Sorting import mergeSort
  10. from graph.Graph_IncidenceList import GraphIncidenceList as Graph
  11. from mst.GraphHelper import GraphHelper
  12. from mst.mst import MST
  13.  
  14.  
  15. def _parseargs( ):
  16. parser = argparse.ArgumentParser(description = 'Questo strumento serve per'
  17. 'prendere il numero di nodi ed archi con cui si vuole creare il grafo')
  18. parser.add_argument("nodi",type=int,help="inserire il numero di nodi")
  19. parser.add_argument("archi",type=int,help="inserire il numero di archi:non "
  20. "puo essere maggiore del doppio dei nodi")
  21. parser.add_argument("pesoMassimo",type=int,help="inserire il peso massimo "
  22. "assegnabile ad ogni arco")
  23. parser.add_argument("nomeFunzione",type=str , help="permette di scegliere "
  24. "se avere un grafo che presenti archi con pesi casuali che non vengano "
  25. "perturbati(anche pesi uguali tra loro),pesi pertubati attraverso un "
  26. "contatore o perturbati casualmente, inserendo rispettivamente : casuale,"
  27. "contatorePerturbato o casualePerturbato")
  28. args = parser.parse_args()
  29. return args
  30.  
  31.  
  32. def randomEdge(nodes,maxWeight,funcName):
  33. """crea un arco avente testa,coda e peso casuali"""
  34. head = random.randint(0,nodes-1)
  35. tail = random.randint(0,nodes-1)
  36. while head == tail:
  37. tail = random.randint(0,nodes-1)
  38. if funcName=='casuale': #assegna all'arco un peso rappresentato
  39. weight = random.randint(0,maxWeight) # da un intero casuale
  40. if funcName=='casualePerturbato': #assegna all'arco un peso intero che viene
  41. weight = random.randint(0,maxWeight)+random.random() #perturbato con un
  42. return(head,tail,weight) #decimale di 16 cifre dopo la virgola
  43.  
  44. def randomEdge_1(nodes,maxWeight,count): #variante della fuznione precedente che
  45. head = random.randint(0,nodes-1)#perturba il peso dell'arco con un contatore
  46. tail = random.randint(0,nodes-1) #di 13 cifre decimali
  47. while head == tail:
  48. tail = random.randint(0,nodes-1)
  49. weight = random.randint(0,maxWeight)+count
  50. return (head,tail,weight)
  51.  
  52.  
  53. def BGR(nodes,edges,maxWeight,funcName):
  54. """genera un grafo casuale rappresentato tramite liste di incidenza"""
  55. if edges > (2*nodes):
  56. edges = int(input("inserire un numero di archi uguale massimo al doppio"
  57. "dei nodi"))
  58. if nodes <= 0:
  59. print("il grafo è vuoto")
  60. return
  61. if nodes == 1 and edges > 0:
  62. print("impossibile creare archi aventi stesso vertice come testa e coda")
  63. return
  64. g = Graph()
  65. n =[]
  66. ginfo = ()
  67. for i in range(nodes):
  68. n.append(g.insertNode(i))
  69. if funcName == "contatorePerturbato":
  70. count = 0.0000000000000 #contatore per il perturbamento manuale del peso
  71. for e in range(edges): #dell'arco
  72. ginfo = ginfo + (randomEdge_1(nodes,maxWeight,count),)
  73. count = count + 0.0000000000001
  74. else:
  75. for e in range(edges):
  76. ginfo = ginfo + (randomEdge(nodes,maxWeight,funcName),)
  77. for e in ginfo:
  78. g.insertEdge(e[0], e[1], e[2])
  79. g.insertEdge(e[1], e[0], e[2])
  80. #g.printGraph() # printa il grafo prima che cleanGraph venga chiamato
  81. c = GraphHelper() # nel caso lo si volesse visualizzare
  82. c.cleanGraph(g)
  83. g.printGraph()
  84. return g
  85.  
  86. def graphEdges(graph):
  87. """crea una lista di tuple rappresentanti gli archi all'interno
  88. delle liste di incidenza (o del grafo)"""
  89. nodes = len(graph.nodes)
  90. edgesList = []
  91. for i in range(nodes):
  92. curr = graph.inc[i].getFirstRecord()
  93. while curr != None:
  94. edge = curr.elem
  95. head = edge.head
  96. tail = edge.tail
  97. weight = edge.weight
  98. edgesList.append((head,tail,weight))
  99. curr = curr.next
  100. print ("\n")
  101. return edgesList
  102.  
  103. def find(parent,i):
  104. """strumento per il controllo dei vertici(se parti dello stesso mst)"""
  105. if parent[i] == i:
  106. return i
  107. return find(parent,parent[i])
  108.  
  109. def union(parent,rank,x,y):
  110. """strumento per la formazione dei supervertci: unisce piu vertici in uno"""
  111. xroot = find(parent,x)
  112. yroot = find(parent,y)
  113. if rank[xroot] < rank[yroot]:
  114. parent[xroot] = yroot
  115. elif rank[yroot] > rank[yroot]:
  116. parent[yroot] = xroot
  117. else:
  118. parent[yroot] = xroot
  119. rank[xroot] += 1
  120.  
  121. def boruvka(graph):
  122. """Genera il Minimo Albero Ricoprente di un grafo secondo l'algoritmo di
  123. Boruvka implementato con il concetto di union by rank"""
  124. mstlist = []
  125. trees = len(graph.nodes) #inizializza ogni vertice come singolo albero
  126. mstweight = 0
  127. father = []
  128. rank = []
  129. cheapest = []
  130. edgesList = graphEdges(graph) #lista con gli archi del grafo
  131. for i in range(len(graph.nodes)):
  132. father.append(i) #lista contenente tutti i vertici
  133. rank.append(0) #Gli alberi con rank inizializzato a 0
  134. cheapest = [-1] * len(graph.nodes) #inizializzo la lista degli archi meno
  135. while trees > 1: #costosi a -1
  136. for i in range(len(edgesList)):
  137. head,tail,weight = edgesList[i] #assegno una variabile per ogni
  138. value1 = find(father, head) #elemento dell'arco in posizione i-esima
  139. value2 = find(father , tail) #contenuto in edgesList
  140. if value1 != value2:
  141. if cheapest[value1] == -1 or cheapest[value1][2] > weight :
  142. cheapest[value1] = [head , tail ,weight]
  143. if cheapest[value2] == -1 or cheapest[value2][2] > weight :
  144. cheapest[value2] = [head , tail ,weight]
  145. for node in range(len(graph.nodes)):
  146. if cheapest[node] != -1:
  147. head,tail,weight = cheapest[node] #assegno una variabile per ogni
  148. value1 = find(father, head) #elemento dell'arco contenuto in cheapest
  149. value2 = find(father ,tail) #in posizione node
  150. if value1 != value2 :
  151. mstweight += weight #aumenta il peso del contatore mst
  152. union(father, rank, value1, value2) #super vertice
  153. mstlist.append((head,tail,weight))
  154. #print ("\nL'arco %d-%d con ampiezza %.*f è incluso nel mst"
  155. #% (head, tail, 16, weight)) #prende le 16 cifre decimali del peso
  156. trees = trees - 1
  157. cheapest = [-1] * len(graph.nodes)
  158. return mstweight,mstlist
  159.  
  160.  
  161.  
  162. if __name__ == "__main__":
  163. _args = _parseargs()
  164. nodes = _args.nodi
  165. edges = _args.archi
  166. maxWeight = _args.pesoMassimo
  167. funcName = _args.nomeFunzione
  168. print('Il Grafo\n')
  169. g = BGR(nodes,edges,maxWeight,funcName)
  170.  
  171.  
  172. print("\n Algoritmo di Boruvka :")
  173. cProfile.run('w1, mst1 = boruvka(g)','statisticheBoruvka')
  174. print("\nIl peso totale del mst è %.*f\n"%(16, w1))
  175. print("\nGli archi che compongono il Minimo Albero Ricoprente sono: \n")
  176. print(mst1)
  177. p = pstats.Stats('statisticheBoruvka')
  178. p.strip_dirs().sort_stats('time').print_stats()
  179.  
  180.  
  181. print("\n Algoritmo di Kruskal :")
  182. cProfile.run('w2, mst2 = MST.kruskal(g)','statisticheKruskal')
  183. print("\nIl peso totale del mst è %.*f\n"%(16, w2))
  184. print("\nGli archi che compongono il Minimo Albero Ricoprente sono:\n")
  185. print([str(item) for item in mst2])
  186. p = pstats.Stats('statisticheKruskal')
  187. p.strip_dirs().sort_stats('time').print_stats()
  188.  
  189.  
  190. print("\n Algoritmo di Prim :")
  191. cProfile.run('w3, mst3 = MST.prim(g)','statistichePrim')
  192. print("\nIl peso totale del mst è %.*f\n"%(16, w3))
  193. bfs = mst3.BFS()
  194. print("BFS sul mst prodotto:")
  195. print([str(item) for item in bfs])
  196. p = pstats.Stats('statistichePrim')
  197. p.strip_dirs().sort_stats('time').print_stats()
  198.  
  199. if(w1 == w2) and (w1 == w3):
  200. print("Computato stesso peso dai 3 algoritmi.")
  201. else:
  202. print("Error! I tre algoritmi tornano un peso totale differente!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement