Guest User

Untitled

a guest
Jun 25th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.86 KB | None | 0 0
  1. '''Task 104. Find the most valuable path in the weighed non-oriented graph.
  2. The value of path is calculated as the product of weights of graph edges.
  3.  
  4. The used algorithm deals with Diixtra approach. It represents the breadth-first search.
  5. The code is detailed, has comments, some duck tapes, is not optimized and so on.
  6. '''
  7.  
  8. import operator as op
  9.  
  10. def task104(N, roads):
  11. # Constructing adjacency matrix for graph
  12. V = [[0] * N for _ in range(N)]
  13. for road in roads:
  14. V[road[0] - 1][road[1] - 1] = road[2] / 100.
  15. V[road[1] - 1][road[0] - 1] = road[2] / 100.
  16.  
  17. # Constructing auxiliary arrays:
  18. # - values is an array of survival probabilities for every crossroad,
  19. # - paths is an array of optimal paths to every crossroad,
  20. # - closed is a set of visited graph nodes (crossroads),
  21. # - order_of_visit is an array which represents the order of visiting graph nodes
  22. values = [0] * N
  23. paths = [str(i + 1) for i in range(N)]
  24. closed = set()
  25. order_of_visit = []
  26.  
  27. # Starting with a node number one
  28. values[0] = 1
  29. paths[0] = '1'
  30. order_of_visit.append(0)
  31.  
  32. while order_of_visit:
  33. # Find the node with maximum survival probability
  34. order_of_visit.sort(key=lambda i: values[i], reverse=True)
  35. current = order_of_visit[0]
  36.  
  37. # Getting a list of neighbouring nodes sorted by survival probability
  38. current_roads = sorted(enumerate(V[current]), key=op.itemgetter(1), reverse=True)
  39.  
  40. # Visiting neighbour nodes:
  41. for road in current_roads:
  42.  
  43. # Skip node if it is already visited or cannot be visited from the current one
  44. if road[0] in closed or not road[1]:
  45. continue
  46.  
  47. # Otherwise add node to the visiting queue
  48. order_of_visit.append(road[0])
  49.  
  50. # Survival probability in case we use the current path
  51. prob = values[current] * road[1]
  52.  
  53. # If new probability is more than the existing value, we remember this path:
  54. if values[road[0]] < prob:
  55. values[road[0]] = prob
  56. paths[road[0]] = paths[current] + '-' + str(road[0] + 1)
  57.  
  58. # This crossroad is visited
  59. closed.add(current)
  60. del order_of_visit[0]
  61.  
  62. return values[-1], paths[-1]
  63.  
  64.  
  65. roads = [[1, 2, 98], [1, 3, 50], [1, 4, 20], [2, 4, 99], [3, 4, 70]]
  66. print('Chance of survival: {:.2f}, path is \'{}\''.format(*task104(4, roads))) # (0.97, '1-2-4')
  67.  
  68. roads = [[1, 2, 98], [1, 3, 97], [1, 6, 15], [2, 4, 99], [2, 5, 100], [3, 4, 70], [4, 6, 99]]
  69. print('Chance of survival: {:.2f}, path is \'{}\''.format(*task104(6, roads))) # (0.96, '1-2-4-6')
  70.  
  71. roads = [[1, 3, 99], [3, 5, 70], [2, 5, 99], [2, 4, 98], [4, 6, 86], [5, 7, 47], [6, 7, 77]]
  72. print('Chance of survival: {:.2f}, path is \'{}\''.format(*task104(7, roads))) # (0.45, '1-3-5-2-4-6-7')
Add Comment
Please, Sign In to add comment