이 동적 프로그래밍 및 백 추적과 하이브리드 솔루션의 더 많은 것이다. 우리는이 문제를 해결하기 위해 Back Tracking 만 사용할 수 있지만 솔루션을 찾으려면 철저한 검색 (2^N)을 수행해야합니다. DP 부분은 뒤로 추적의 검색 공간을 최적화합니다.
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])
출력이 입력
MinimumSum = 31
MaxArraySize = 3
InputData = sorted([1,4,5,10,17,34])
출력이
[34]
같이
[5, 10, 17]
이다
3,691,363,210
프로그램의이 부분은 모두의 합이다 (최대 가능한 수의 1 내지 수의 합계를 만들기 위해 요구되는 입력 데이터로부터 수의 최소 수를 발견
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
프로그램의이 부분은 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로 제한하고리스트가'[1,4,5,10,17,37]'일 경우 37을 합한 값으로 제한하려면'[37]'또는' [1,4,5,10,17]'? – lurker
http://en.wikipedia.org/wiki/Knapsack_problem의 유사 콘텐츠입니다. –
@mbratch : 37로 돌아갑니다. – crough