Advertisement
Guest User

p11.py

a guest
Oct 10th, 2012
1,205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # 6.00 Problem Set 11
  2. #
  3. # ps11.py
  4. #
  5. # Graph optimization
  6. # Finding shortest paths through MIT buildings
  7. #
  8.  
  9. import string
  10. from graph import Digraph, Edge, Node, Rode,campusMap
  11.  
  12. #
  13. # Problem 2: Building up the Campus Map
  14. #
  15. # Write a couple of sentences describing how you will model the
  16. # problem as a graph)
  17. #
  18. def load_map(mapFilename):
  19.     """
  20.    Parses the map file and constructs a directed graph
  21.  
  22.    Parameters:
  23.        mapFilename : name of the map file
  24.  
  25.    Assumes:
  26.        Each entry in the map file consists of the following four positive
  27.        integers, separated by a blank space:
  28.            From To TotalDistance DistanceOutdoors
  29.        e.g.
  30.            32 76 54 23
  31.        This entry would become an edge from 32 to 76.
  32.  
  33.    Returns:
  34.        a directed graph representing the map
  35.    """
  36.     #TODO
  37. """
  38. The IDLE gives the following error:
  39. Loading map from file...
  40. ---------------
  41. Test case 1:
  42. Find the shortest-path from Building 32 to 56
  43.  
  44. Traceback (most recent call last):
  45.  File "D:\asign1\11\ps11.py", line 170, in <module>
  46.    brutePath1 = bruteForceSearch(digraph, '32', '56', LARGE_DIST, LARGE_DIST)
  47.  File "D:\asign1\11\ps11.py", line 96, in bruteForceSearch
  48.    raise ValueError("Start or end not in graph.")
  49. ValueError: Start or end not in graph.
  50. """  
  51. ## So I am thinking there's something wrong with my code for this fcn.
  52. ## Yet when i add print statement to print the whole graph built by this fcn, I see the node '32' and ##'56' (32->56)...I'm confused now.If 32 and 56 already in the graph, how could this error be given???
  53. ## There are probably some other bugs in my code,for now I only want to fix this one so that i can move ##on.So take a look at this if got time...Thanks in advance.
  54. ##
  55. ##Details added on 3:05 PM UTC/GMT +8 hours Wednesday, October 10, 2012
  56. """
  57. I add some print fcn in grapy.py(in my second code post) and found the following info in idle:
  58. Loading map from file...
  59. hasNode() in Digraph called.
  60. addNode() in campusMap called.
  61. Node  32  added.
  62. hasNode() in Digraph called.
  63. addNode() in campusMap called.
  64. Node  36  added.
  65. Rode  32->36     distance: 70  outside distance: 0  added
  66. hasNode() in Digraph called.
  67. addNode() in campusMap called.
  68. Node  36  added.
  69. hasNode() in Digraph called.
  70. addNode() in campusMap called.
  71. Node  32  added.
  72. Rode  36->32     distance: 70  outside distance: 0  added
  73. ...
  74. So node 32 and node 36 are added more than once, it seems
  75. if not g.hasNode(nPair0):
  76.   g.addNode(nPair0)
  77. and
  78. if not g.hasNode(nPair1):
  79.   g.addNode(nPair1)
  80. did not prevent this,"hasNode() in Digraph called." proves that Digraph.hasNode() has been called but duplicate node still walk into nodes set without ValueError('Duplicate node') being raised!??? And the error mentioned above this addtional description still is annoying me.So could any one take at a look at this?
  81. """
  82. ##    nodes = []
  83.     print "Loading map from file..."
  84.     g = campusMap()
  85.     dataFile = open(mapFilename, 'r')
  86.     for line in dataFile:
  87.         if len(line) == 0:
  88.             continue
  89.         dataLine = string.split(line)
  90.         nPair0 = Node(str(dataLine[0]))
  91.         nPair1 = Node(str(dataLine[1]))
  92.         if not g.hasNode(nPair0):
  93.             g.addNode(nPair0)
  94.         if not g.hasNode(nPair1):
  95.             g.addNode(nPair1)
  96.         rode = Rode(nPair0, nPair1, int(dataLine[2]), int(dataLine[3]))
  97. ##        print rode
  98.         g.addEdge(rode)
  99.     return g
  100.  
  101. ##digraph = load_map("mit_map.txt")
  102. #
  103. # Problem 3: Finding the Shortest Path using Brute Force Search
  104. #
  105. # State the optimization problem as a function to minimize
  106. # and the constraints
  107. #
  108.  
  109. def bruteForceSearch(digraph, start, end, maxTotalDist, maxDistOutdoors, visited = [], dist = [], outdoorDist = [], toPrint = True):    
  110.     """
  111.    Finds the shortest path from start to end using brute-force approach.
  112.    The total distance travelled on the path must not exceed maxTotalDist, and
  113.    the distance spent outdoor on this path must not exceed maxDisOutdoors.
  114.  
  115.    Parameters:
  116.        digraph: instance of class Digraph or its subclass
  117.        start, end: start & end building numbers (strings)
  118.        maxTotalDist : maximum total distance on a path (integer)
  119.        maxDistOutdoors: maximum distance spent outdoors on a path (integer)
  120.  
  121.    Assumes:
  122.        start and end are numbers for existing buildings in graph
  123.  
  124.    Returns:
  125.        The shortest-path from start to end, represented by
  126.        a list of building numbers (in strings), [n_1, n_2, ..., n_k],
  127.        where there exists an edge from n_i to n_(i+1) in digraph,
  128.        for all 1 <= i < k.
  129.  
  130.        If there exists no path that satisfies maxTotalDist and
  131.        maxDistOutdoors constraints, then raises a ValueError.
  132.    """
  133.     #bruteForceSearch(digraph, start, end, maxTotalDist, maxDistOutdoors,
  134.     #/ visited = [], dist = [], outdoorDist = [], toPrint = False)
  135.     #TODO
  136.     global numCalls
  137.     numCalls += 1
  138. ##    print numCalls
  139.     if not (digraph.hasNode(start) and digraph.hasNode(end)):
  140.         print 'start: ', start, 'end: ',end
  141.         #print digraph
  142.         raise ValueError("Start or end not in graph.", start, end, digraph.__str__)
  143.     if toPrint:
  144.         print "    "*numCalls, "Finding path from ",start," to ",end
  145.     path = [str(start)]
  146.     if start == end:
  147.         if toPrint: print "    "*numCalls, "Not looking at path from ", start, " to itself."
  148.         numCalls -=1
  149.         return path
  150.     shortest = None
  151.     for node in digraph.childrenOf(start):
  152.         if (str(node) not in visited):
  153.             visited = visited + [str(node)]
  154.             dist.append(digraph.edges[start][node][0])
  155.             outdoorDist.append(digraph.edges[start][node][1])
  156.             prveCost = sum(outdoorDist)
  157.             newPath = bruteForceSearch(digraph, node, end, maxTotalDist, maxDistOutdoors, visited, dist, outdoorDist, toPrint)
  158.             if sum(maxTotalDist) >= maxTotalDist or sum(outdoorDist) >= maxDistOutdoors:
  159.                 newPath = None
  160.                 dist = []
  161.                 outdoorDist = []
  162.             if newPath == None:
  163.                 continue
  164.             if (shortes == None or prveCost > sum(outdoorDist)):
  165.                 shortest = newPath
  166.         if shortes != None:
  167.             path = path + shortest
  168.         else:
  169.             path = None
  170.         if toPrint: print "    "*numCalls, "Path from node ",start, " to ",end, " was: ",path
  171.         return path
  172.                
  173.      
  174. #
  175. # Problem 4: Finding the Shorest Path using Optimized Search Method
  176. #
  177. def directedDFS(digraph, start, end, maxTotalDist, maxDistOutdoors):
  178.     """
  179.    Finds the shortest path from start to end using directed depth-first.
  180.    search approach. The total distance travelled on the path must not
  181.    exceed maxTotalDist, and the distance spent outdoor on this path must
  182.     not exceed maxDisOutdoors.
  183.  
  184.    Parameters:
  185.        digraph: instance of class Digraph or its subclass
  186.        start, end: start & end building numbers (strings)
  187.        maxTotalDist : maximum total distance on a path (integer)
  188.        maxDistOutdoors: maximum distance spent outdoors on a path (integer)
  189.  
  190.    Assumes:
  191.        start and end are numbers for existing buildings in graph
  192.  
  193.    Returns:
  194.        The shortest-path from start to end, represented by
  195.        a list of building numbers (in strings), [n_1, n_2, ..., n_k],
  196.        where there exists an edge from n_i to n_(i+1) in digraph,
  197.        for all 1 <= i < k.
  198.  
  199.        If there exists no path that satisfies maxTotalDist and
  200.        maxDistOutdoors constraints, then raises a ValueError.
  201.    """
  202.     #TODO
  203.     pass
  204.  
  205. # Uncomment below when ready to test
  206. if __name__ == '__main__':
  207.     # Test cases
  208.     digraph = load_map("mit_map.txt")
  209.    
  210.     LARGE_DIST = 1000000
  211.  
  212.     # Test case 1
  213.     print "---------------"
  214.     print "Test case 1:"
  215.     print "Find the shortest-path from Building 32 to 56"
  216.     expectedPath1 = ['32', '56']
  217.     numCalls = -1
  218.     brutePath1 = bruteForceSearch(digraph, '32', '56', LARGE_DIST, LARGE_DIST)
  219. ##    dfsPath1 = directedDFS(digraph, '32', '56', LARGE_DIST, LARGE_DIST)
  220.     print "Expected: ", expectedPath1
  221.     print "Brute-force: ", brutePath1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement