我想创建一个新函数,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
的nrst
列表,但速度很慢(必须重新运行多次)。但是,neighbor_trial
不能正确更新。必须检查每个atom
' 的nrst
邻居以查看trialatom
现在是否是邻居,并重新创建列表被擦除nrst
的atom
' 的列表。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])