追踪解
追踪解,上述实现的情况下,解都在最后一层,根本不知道之前的路径是怎样的,广度优先搜索,同一个纬度,假如不加指标判断的话,根本不知道最优解是选择的哪一个,所以需要同一个纬度的每一个结点,记住他之前的路径,才能在最优解的时候之前是怎么走过来的,每一个结点用一个数组记录路径,这样实现的感觉消耗有点大啊,通常看见是采用链表方式
限界分支法本质还是空间树,树的话,还是用链表实现比较容易和直观
把之前实现基于数组的形式修改成结点链表方式
实现如下:
#%%
# 修改成结点,为了追踪解,新增两个变量,是否选择物品和前一个物品的结点
class Node:
def __init__(self, CurCost=None,CurValue=None,Flag=None,parent=None):
# 部分解所占体积
self.CurCost = CurCost
# 部分解所占价值
self.CurValue = CurValue
# 当前结点是否选择了物品
self.isleft = Flag
# 前一个结点是谁
self.parent = parent
class FIFO_01_Pack_with_solution_tracking:
def __init__(self,N,V,C,W):
self.num =N
self.Volume = V
self.Cost = C
self.Value = W
# 存放最优解
self.BestResult = [False]*N
# 最优解结点,这里是叶子结点
self.BestNode = Node(0,0,False,None)
#用于存放活结点,便于理解,把根结点,以及第0层结束标志-1放进去
# 结点包括2个属性:当前空间大小,当前的价值大小
self.queue = [Node(0,0,False,None),Node(-1,-1,False,None),]
# 实现时叶子结点不加入到活结点列表,当属于叶子结点时,增加对结果的处理
def enQueen(self,node,depth):
if depth == self.num -1:
CurValue = node.CurValue
if CurValue > self.BestNode.CurValue:
self.BestNode.CurValue = CurValue
self.BestNode.isleft = node.isleft
self.BestNode.parent = node.parent
else:
self.queue.append(node)
def pack_01(self):
# selected = [0]*self.num
# 首先取出根结点
depth = 0
node = self.queue.pop(0)
CurCost = node.CurCost
CurValue = node.CurValue
while True:
# 判断左结点能否加入到队列,能的话,把当前空间和当前价值放入队列
if CurCost + self.Cost[depth] < self.Volume:
# 这时的父节点就是node
self.enQueen(Node(CurCost + self.Cost[depth],CurValue + self.Value[depth],True,node),depth)
# 右结点总是可以加入队列的,因为没有约束条件的限制
self.enQueen(Node(CurCost,CurValue,False,node),depth)
# 然后弹出下一个结点
node = self.queue.pop(0)
CurCost = node.CurCost
CurValue = node.CurValue
# 当同一层处理完毕时,先判断是否能够输出结果,判断的标准是队列是否为空,
# 这时下一层的所有结点已经加入了队列,这时需要把下一层
# 增加一个结尾-1便于判断,然后进入下一层,弹出下一个结点
if CurCost == -1:
if not self.queue:
return self.BestNode.CurValue
self.enQueen(Node(-1,-1,False,None),depth)
depth += 1
node = self.queue.pop(0)
CurCost = node.CurCost
CurValue = node.CurValue
def solution_Tracking(self):
#追踪解从self.BestNode开始追踪
for j in range(self.num-1,-1,-1):
self.BestResult[j] = self.BestNode.isleft
self.BestNode = self.BestNode.parent
return self.BestResult
def print_Result(self):
print(self.pack_01())
print(self.solution_Tracking())
N = 8
V = 30
C = [11,2,3,9,13,6,15,7,19]
W = [5.0,2.0,5.0,7.0,5.0,11.0,6.0,14.0]
FIFO_01_Pack_with_solution_tracking(N,V,C,W).print_Result()
39.0
[False, True, True, True, False, True, False, True]