-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathBackKnap.py
71 lines (64 loc) · 1.91 KB
/
BackKnap.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# coding: utf-8
__author__ = 'devin'
class BackKnap(object):
def __init__(self, weight=[], value=[]):
if len(weight) != len(value):
raise Exception("w,v must have same length!")
self._weight = weight
self._value = value
self._n = len(weight)
self._solution = []
def boundF(self, cp, cw, k, M):
"""
:param cp:
:param cw:
:param M:
:return: maxValue
"""
b = cp
c = cw
for i in range(k, self._n):
c += self._weight[i]
if c < M:
b += self._value[i]
else:
return b + (1 - (c-M)/self._weight[i])*self._value[i]
return b
def backKnap(self, M):
cw = 0
cp = 0
k = 0
fp = -1
Y = [0 for i in range(self._n)]
X = [0 for i in range(self._n)]
while True:
while k < self._n and cw + self._weight[k] <= M:
cw = cw + self._weight[k]
cp = cp + self._value[k]
Y[k] = 1
k += 1
if k > self._n - 1:
fp = cp
k = self._n -1
X = Y[:]
self._solution.append(X)
else:
Y[k] = 0
while self.boundF(cp, cw, k+1, M) <= fp: # 必须是k+1,若是k第一次探索, fp=-1,boundF()永远不会小于等于-1,会死循环
while k != -1 and Y[k] != 1:
k -= 1
if k == -1:
return X
Y[k] = 0
cw -= self._weight[k]
cp -= self._value[k]
k += 1
def getSolution(self):
return self._solution
if __name__ == '__main__':
w = [1, 11, 21, 23, 33, 43, 45, 55]
v = [11, 21, 31, 33, 43, 53, 55, 65]
s = BackKnap(w, v)
res = s.backKnap(110)
print res
print s.getSolution()