如何解决修改后的背包问题陷入无限循环
我一直在尝试实现一个关于生物信息学的改进的背包问题算法。
在我看来,到目前为止,我已经非常接近解决方案,但是程序在某个点卡住了。
我有一个节点列表,这些节点具有(某种氨基酸的)质量、索引以及它们可以到达的节点列表。
节点:
class Node():
def __init__(self,mass,index):
self.mass = mass
self.prev = []
self.next = []
self.index = index
def chainTo(self,next):
self.next.append(next)
next.prev.append(self)
目标是从给定的节点中找到可能的最长链,这样我就可以从它们的质量中找出它们代表的肽段。
为此,我编写了一个函数,如果 nodes[i].mass - nodes[j].mass 等于.txt 文件中预定义的一些氨基酸质量。
def createTree(masstable,massDev,aminoTable,extras):
nodes = createNodes()
for i in range(0,len(nodes)):
for j in range(i+1,len(nodes)):
findamino(nodes[i],nodes[j],masstable,extras)
return nodes
def findamino(first,second,extras):
found = False
for amino,mass in masstable.items():
for extra,extraMass in extras.items():
#print(first.mass - second.mass)
if ((mass + extraMass - massDev) <= abs(first.mass - second.mass) <= (mass + extraMass + massDev)):
first.chainTo(second) #pravimo vezu
#print(amino)
aminoTable.update({(first,second) : amino})
found = True
break
return False if not found else True #ako ne nađe niti jednu mogućnost,vraća False
所以代码的最后和主要部分是遵循特定规则的树遍历算法:
- 从列表中取出第一个节点(如果它的下一个列表中没有节点,则取第二个,依此类推)
- 调用树遍历算法找到所有可能的路径(例如,如果节点[0]在其下一个列表中有节点[1]和节点[2],那么树遍历算法必须找到路径节点[ 0]->节点[1]和节点[0]->节点[2]
- 在所有生成的路径中,程序占用的路径最长
- 程序重复第 1 步,但它不会从列表中获取第一个节点,而是获取最长找到路径中最后一个节点之后的节点
- 当涉及到最后一个节点时,它结束并返回最长可能链的列表。
def traverseRoot(root,chains):
traverse(root,[],chains)
#node - čvor na kojem se nalazimo
#ako nema susjede,u chains dodajemo taj put
#ako ima,pokrecemo isti algoritam
def traverse(node,path,chains):
path.append(node)
if(len(node.next) == 0):
chains.append(path)
else:
for i in node.next:
print(str(i.mass) + " " + str(i.index))
traverse(i,path.copy(),chains)
def start(nodes,extras):
#IDEJA:
#1. funkcija uzima prvi čvor (ukoliko nema prijelaze,uzima idući,pa idući,itd.)
#2. nad tim čvorom provodi neku vrstu tree-traversing algoritma kako bi prošao sve puteve
#3. uzima kao konačni put onaj koji je došao najdalje u listi / pokrio najviše čvorova
#4. ponavlja sve počevši od prvog koraka samo što ne uzima prvi čvor nego onaj koji dolazi nakon zadnjeg u prethodno pronađenom putu
#5. kad dođe do zadnjeg čvora,prestaje sa radom i vraća listu stvorenih lanaca po čijim čemo vezama gledati koje aminokiseline predstavljaju
start = 0
finalChains = []
while(True):
currentNodeChains = []
found = False
for i in range(start,len(nodes)):
if(not nodes[i].next): #1.
continue
else:
found = True
print(start)
traverseRoot(nodes[i],currentNodeChains) #2.
break
if (not found):
return finalChains
#3.
maxLen = 0
maxChain = None
for chain in currentNodeChains:
if (len(chain) > maxLen):
maxLen = len(chain)
maxChain = chain
if (maxChain != None):
finalChains.append(maxChain)
print([i for i in maxChain])
print("-----------")
start = maxChain[-1].index + 1 #4.
return finalChains
我的整个问题是程序在某个点卡住了。
例如,我有 300 个节点,它在接近结束时陷入无限循环,在我运行它的示例中大约是第 280 个节点。
我怀疑它是否必须对我正在运行的这个特定示例执行某些操作,但更有可能在递归函数调用中的某处存在逻辑错误。
如果有人知道问题出在哪里,我将不胜感激!
解决方法
在尝试调试代码时,问题似乎出在 Node 类中属性 next 的整个概念上。
当我打印出所有节点的下一个列表时,我发现同一节点多次出现,例如 [2,2,3,8,...] 所以当我转换 列表时设置它不再卡住了。
希望这对未来的人有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。