2015-11-05 74 views
0

我最近在學習Python,並且知道通常存在一些很好的庫/函數,我們不需要編寫自己的函數。我認爲我面臨的問題是一個排列/組合問題,可以用Python很容易地解決,itertools,但不完全確定如何。Python中的排列/組合

問題是...我想在漢堡的地方訂購一套完美的價格,我想要支付。該組合包括1個漢堡(opt1)和1個側面+飲料(opt2),可選配1個側面(opt3)和特殊飲料升級選項。

樣本數據集:(ID,價格,描述)

opt1 = [(1,24,'Beef'),(2,26,'Cheese'),(3,29,'Veggie'),(4,24,'Chicken'),(5,25,'Bacon')] 
opt2 = [('A',18,'S Fries'),('B',21,'L Fries'),('C',19,'Nuggets'),('D',22,'Pudding')] 
opt3 = [('A',14,'S Fries'),('B',17,'L Fries'),('C',13,'Nuggets'),('D',16,'Pudding'),('-',0,'-')] 
opt4 = [('Z',3,'Special Drink'),('-',0,'-')] 

說,如果我定位到訂單價格58的組合,我可以這樣做:

def find_combo(target_price): 
    for x in opt1: 
     for y in opt2: 
      for z in opt3: 
       for w in opt4: 
        if x[1] + y[1] + z[1] + w[1] == target_price: 
         print "{}:{} {}:{} {}:{} {}:{}".format(x[0],x[2],y[0],y[2],z[0],z[2],w[0],w[2]) 

find_combo(58) 

以上工作正常,給我可能的組合選項。

1:Beef A:S Fries C:Nuggets Z:Special Drink 
1:Beef A:S Fries D:Pudding -:- 
1:Beef B:L Fries C:Nuggets -:- 
4:Chicken A:S Fries C:Nuggets Z:Special Drink 
4:Chicken A:S Fries D:Pudding -:- 
4:Chicken B:L Fries C:Nuggets -:- 
5:Bacon C:Nuggets A:S Fries -:- 

這裏是一個問題,我有一個感覺,4 for循環對於更聰明地使用Python沒有必要。那麼如何更智能地計算呢?

+0

你可以發佈你的函數的輸出? –

回答

2

你必須明確地探索整個搜索空間......貪婪算法不會工作

def price(*opts): 
    return sum(o[1] for o in opts) 

exact_matches = [combo for combo in itertools.product(opt1,opt2,opt3,opt4) if price(*combo) == target] 
cheaper_matches = [combo for combo in itertools.product(opt1,opt2,opt3,opt4) if price(*combo) < target] 

這在本質上是一樣的四個迴路只用一個python內置上方...引擎蓋下的仍然只是循環