2016-04-07 7 views
7

में लघु पथ एल्गोरिदम के लिए कार्यात्मक समाधान मैं Learn You Some Erlang for Great Good! पढ़ रहा हूं और दिलचस्प पहेली पाई। मैंने इसे पायथन में सबसे कार्यात्मक तरीके से लागू करने का निर्णय लिया। short path mapपायथन

कृपया मेरे कोड देखें:

def open_file(): 
    file_source = open('resource/path.txt', 'r') # contains 50\n 10\n 30\n 5\n 90\n 20\n 40\n 2\n 25\n 10\n 8\n 0\n 
    return file_source 


def get_path_tuple(file_source, pathList=[]): 
    try: 
     node = int(next(file_source)), int(next(file_source)), int(next(file_source)) 
     pathList.append(node) 
     get_path_tuple(file_source, pathList) 
    except StopIteration: 
     pass 
    return pathList 


def short_step(pathList, n, stepList): 
    try: 
     stepA = pathList[n][0] + pathList[n][1] 
     stepB = pathList[n][1] + pathList[n][2] 
     stepList.append(min([stepA, stepB])) 
     short_step(pathList, n+1, stepList) 
    except IndexError: 
     pass 
    return stepList 


pathList = get_path_tuple(open_file(), []) 
pathList.reverse() 
print(short_step(pathList, 0, [])) 

लेकिन मैं इस समस्या में मारा, मैं कैसे वर्तमान स्थान के राज्य रखने के लिए पता नहीं है। परिणाम है: [8, 27, 95, 40]। क्या आप कृपया मेरे कोड को ठीक करने में मदद कर सकते हैं।

+0

बस एक त्वरित नोट, अपने 'get_path_tuple' में' pathList = []' से सावधान रहें। आप इसे एक खाली सूची में सेट कर रहे हैं जो कि परिवर्तनीय है, और डिफ़ॉल्ट तर्क मानों का फ़ंक्शन परिभाषा समय पर केवल एक बार मूल्यांकन किया जाता है, इसलिए फ़ंक्शन के अंदर इसे संशोधित करने से उस फ़ंक्शन के बाद की सभी कॉल प्रभावित हो जाएंगी। फ़ंक्शन की पहली पंक्ति में एक प्रिंट स्टेटमेंट दें और इसे कई बार कॉल करें और आप देखेंगे कि मेरा क्या मतलब है। – fips

उत्तर

1

इस विशिष्ट मामले में, और अपने डेटा संरचना का उपयोग, ऐसा लगता है कि आप समानांतर में दो स्थितियों को चलाने के लिए सक्षम होना चाहिए:

बी के एक
  • लागत की
    • लागत

    आप वर्तमान लागत को बनाए रख सकते हैं, और आपके द्वारा एकत्रित डेटा तीसरे तत्व में "स्विच करने की लागत" प्रदान करता है।

    तो आपको पूछना होगा: कौन सा सस्ता है? शुरुआती पथ पर रहना, या दूसरे रास्ते पर स्विच करना?

    path_list = [ 
         (50, 10, 30), 
         (5, 90, 20), 
         (40, 2, 25), 
         (10, 8, 0), 
    ] 
    
    A = 0 
    B = 1 
    Switch = 2 
    
    def cheapest_path(path_list, path=None, history=None): 
        if history is not None: 
         # Terminate when path_list is empty 
         if not path_list: 
          return history 
    
         # Determine cost to stay this path, vs. cost to switch 
         step = path_list[0] 
         path_list = path_list[1:] 
    
         stay_on_path = cheapest_path(path_list, path, history + [step[path]]) 
         switch_path = cheapest_path(path_list, B if path == A else A, history + [step[path], step[Switch]]) 
    
         return switch_path if sum(switch_path) < sum(stay_on_path) else stay_on_path 
        else: 
    
         pathA = cheapest_path(path_list, A, []) 
         pathB = cheapest_path(path_list, B, []) 
         return pathA if sum(pathA) < sum(pathB) else pathB 
    
    print(", ".join(map(str, cheapest_path(path_list)))) 
    
  • +0

    एक बहुत ही सुंदर समाधान। तुमने ये कैसे किया? क्या सुधार के लिए कोई पहेली/किताबें हैं "रिकर्सिव अंतर्ज्ञान"? –

    +0

    यह समाधान डेटा को स्टोर करने के लिए आपके द्वारा चुने गए तरीके से सीधे बाहर आता है। यह वास्तव में मेरे लिए कुछ हद तक अंतर्ज्ञानी था, क्योंकि मेरा झुकाव वर्तमान चरण की लागत जोड़ने से पहले पथ स्विच करना था। –

    1

    वास्तव में, मुझे लगता है कि सभी पथदर्शी समस्याओं में, आपको कुल पथ की लंबाई से प्रत्येक बिंदु तक गणना करना होगा। फिर आपको दोनों की गणना करना होगा, बी के पथ की सूची और बी

    मुझे पता नहीं है कि रिकर्सिव एल्गोरिदम व्यायाम का हिस्सा है लेकिन मैंने एक साधारण लूप का उपयोग किया है।

    pathList = [[50,10,30],[5,90,20],[40,2,25],[10,8,999999]] 
    
    def all_steps(pathList): 
    
        stepListA,stepListB = [],[] 
        for n in range(0,len(pathList)): 
    
         #Step to A 
         if pathList[n][0]<=pathList[n][1] + pathList[n][2]:#A to A 
          new_stepListA = list(stepListA) 
          new_stepListA.append(pathList[n][0]) 
         else: #B to A 
          new_stepListA = list(stepListB) 
          new_stepListA.extend([pathList[n][1],pathList[n][2]])   
    
         #Step to B 
         if pathList[n][1]<=pathList[n][2] + pathList[n][2]:#B to B 
          new_stepListB = list(stepListB) 
          new_stepListB.append(pathList[n][1]) 
         else: #A to B 
          new_stepListB = list(stepListA) 
          new_stepListB.extend([pathList[n][0],pathList[n][2]]) 
    
         stepListA = list(new_stepListA) 
         stepListB = list(new_stepListB) 
    
        if sum(stepListA)<=sum(stepListB): 
         print "finish on A" 
         return stepListA 
        else: 
         print "finish on B" 
         return stepListB 
    
    
    print all_steps(pathList) 
    
    +0

    विचारों के लिए धन्यवाद, लेकिन यह गलत जवाब देता है '[10, 25, 2, 18] '- यह उत्तर नहीं हो सकता है –

    +0

    वैसे 99 99 99 खो गया था और मैंने इसे सही किया लेकिन यह केवल इनपुट डेटा के बारे में है। जवाब तब [10, 25, 2, 8] है जो बाएं से दाएं सबसे अच्छे रास्ते के लिए पूरी तरह से आपकी तस्वीर का उत्तर देने लगता है। अगर नहीं, तो कृपया मुझे बताएं कि आप किस उत्तर की उम्मीद करते हैं। – Vince

    +0

    तस्वीर से हम देख सकते हैं कि सबसे छोटा रास्ता 10 30 5 20 2 8 –