更新先前存在的列表以避免O(n^2)

2024-10-03 09:11:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个新函数neighbor_trial(atomlist,trialatom),它将在O(n)而不是neighbor(atomlist)O(n^2)时间)中运行。我只需更新上一次运行neighbor(atomlist)的结果就可以实现这一点。trialatom是移动的原子,atomlist中的所有其他原子都不移动。你知道吗

背景:

atomlist是Atom类的实例列表。Atom对象有一个函数atom1.is_neighbor(atom2),它检查atom2是否是atom1的最近邻居。如果是,则将atom2添加到atom1.nrst列表中。一个原子最多只能有12个唯一的最近邻,不能包含自己。你知道吗

问题:

neighbor正确更新了每个人的atom列表,但速度很慢(必须多次重新运行)。但是,neighbor_trial没有正确更新。必须检查每个atomnrst邻居,看看trialatom现在是否是邻居,以及重新创建atomnrst列表,该nrst列表的nrst列表被擦除。你知道吗

def neighbor(atomlist): 
    cdef int i, j
    for atom in atomlist:  
        atom.nrst=[]   #Unnecessarily deletes every atom's nrst! 
    for i in range(len(atomlist)):
        for j in range(i+1,len(atomlist)):
            if atomlist[i].is_neighbour(atomlist[j]):
                atomlist[i].nrst.append(atomlist[j])
                atomlist[j].nrst.append(atomlist[i])

def neighbor_trial(atomlist,trialatom):
    cdef int i, j
    redoo_list=[]
    for atom in trialatom.nrst:
        atom.nrst=[]            #Only trialatom and its neighbours' nrst list are wiped!
        redoo_list.append(atom)
    trialatom.nrst = []
    redoo_list.append(trialatom)
    for i in range(len(atomlist)):
        for j in range(len(redoo_list)):
            if atomlist[i] != redoo_list[j]:
                if atomlist[i].is_neighbour(redoo_list[j]):
                    redoo_list[j].nrst.append(atomlist[i])

Tags: in列表forlenrangelistatom原子