यह एक संकर समाधान के अधिक, गतिशील प्रोग्रामिंग और वापस ट्रैकिंग के साथ है। हम इस समस्या को हल करने के लिए अकेले बैक ट्रैकिंग का उपयोग कर सकते हैं, लेकिन फिर हमें समाधान खोजने के लिए संपूर्ण खोज (2^एन) करना है। डीपी भाग बैक ट्रैकिंग में खोज स्थान को अनुकूलित करता है।
import sys
from collections import OrderedDict
MinimumSum = 31
MaxArraySize = 4
InputData = sorted([1,4,5,10,17,34])
# Input part is over
Target = MinimumSum + 1
Previous, Current = OrderedDict({0:0}), OrderedDict({0:0})
for Number in InputData:
for CurrentNumber, Count in Previous.items():
if Number + CurrentNumber in Current:
Current[Number + CurrentNumber] = min(Current[Number + CurrentNumber], Count + 1)
else:
Current[Number + CurrentNumber] = Count + 1
Previous = Current.copy()
FoundSolution = False
for Number, Count in Previous.items():
if (Number >= Target and Count < MaxArraySize):
MaxArraySize = Count
Target = Number
FoundSolution = True
break
if not FoundSolution:
print "Not possible"
sys.exit(0)
else:
print Target, MaxArraySize
FoundSolution = False
Solution = []
def Backtrack(CurrentIndex, Sum, MaxArraySizeUsed):
global FoundSolution
if (MaxArraySizeUsed <= MaxArraySize and Sum == Target):
FoundSolution = True
return
if (CurrentIndex == len(InputData) or MaxArraySizeUsed > MaxArraySize or Sum > Target):
return
for i in range(CurrentIndex, len(InputData)):
Backtrack(i + 1, Sum, MaxArraySizeUsed)
if (FoundSolution): return
Backtrack(i + 1, Sum + InputData[i], MaxArraySizeUsed + 1)
if (FoundSolution):
Solution.append(InputData[i])
return
Backtrack(0, 0, 0)
print sorted(Solution)
नोट: सवाल, न्यूनतम राशि और अधिकतम सरणी आकार में आपके द्वारा दिए गए उदाहरण के अनुसार सख्ती से अधिक से अधिक और मान निर्दिष्ट क्रमश की तुलना में कम कर रहे हैं।
इस इनपुट के लिए
MinimumSum = 31
MaxArraySize = 4
InputData = sorted([1,4,5,10,17,34])
आउटपुट
[5, 10, 17]
के रूप में, इस निवेश के लिए
MinimumSum = 31
MaxArraySize = 3
InputData = sorted([1,4,5,10,17,34])
आउटपुट
[34]
वह जगह है जहाँ है
स्पष्टीकरण
Target = MinimumSum + 1
Previous, Current = OrderedDict({0:0}), OrderedDict({0:0})
for Number in InputData:
for CurrentNumber, Count in Previous.items():
if Number + CurrentNumber in Current:
Current[Number + CurrentNumber] = min(Current[Number + CurrentNumber], Count + 1)
else:
Current[Number + CurrentNumber] = Count + 1
Previous = Current.copy()
कार्यक्रम के इस भाग को इनपुट डेटा, अधिकतम संभव संख्या 1 से संख्याओं का योग करने के लिए आवश्यक से संख्या की न्यूनतम संख्या पाता है (जो सभी का योग है इनपुट डेटा)। Knapsack समस्या के लिए, यह एक गतिशील प्रोग्रामिंग समाधान है। आप इंटरनेट पर इसके बारे में पढ़ सकते हैं।
FoundSolution = False
for Number, Count in Previous.items():
if (Number >= Target and Count < MaxArraySize):
MaxArraySize = Count
Target = Number
FoundSolution = True
break
if not FoundSolution:
print "Not possible"
sys.exit(0)
else:
print Target, MaxArraySize
कार्यक्रम के इस भाग को, जो MaxArraySize
मापदंड से मेल खाने Target
मूल्य पाता है।
def Backtrack(CurrentIndex, Sum, MaxArraySizeUsed):
global FoundSolution
if (MaxArraySizeUsed <= MaxArraySize and Sum == Target):
FoundSolution = True
return
if (CurrentIndex == len(InputData) or MaxArraySizeUsed > MaxArraySize or Sum > Target):
return
for i in range(CurrentIndex, len(InputData)):
Backtrack(i + 1, Sum, MaxArraySizeUsed)
if (FoundSolution): return
Backtrack(i + 1, Sum + InputData[i], MaxArraySizeUsed + 1)
if (FoundSolution):
Solution.append(InputData[i])
return
Backtrack(0, 0, 0)
अब हम जानते हैं कि समाधान मौजूद है, हम समाधान को फिर से बनाना चाहते हैं। हम यहां बैकट्रैकिंग तकनीक का उपयोग करते हैं। आप आसानी से इंटरनेट पर भी इसके बारे में बहुत अच्छे ट्यूटोरियल पा सकते हैं।
यदि आप सरणी आकार को 5 तक सीमित करना चाहते हैं और 37 के योग को क्या करना चाहते हैं तो क्या होगा यदि सूची '1,4,5,10,17,37]' हो, तो क्या आप इसे '[37] 'या' [1,4,5,10,17] '? – lurker
यह http://en.wikipedia.org/wiki/Knapsack_problem –
@mbratch पर भिन्नता जैसा दिखता है: यह 37. – crough