我写了一个python代码,在三维聚合物上执行王兰道算法。在此附上相关代码。
1)原始代码。WL3D.py
from scipy import *
import sys
import numpy as np
from pylab import *
from spinfun import SARW
from spinfun import Energy
from spinfun import Transform
from spinfun import Equality
Niter = int(input("Enter number of MC steps:"))
L=int(input("Enter number of monomers:"))
N=int(input("Enter the dimensions of lattice:"))
spin=zeros((N,N,N), dtype=int)
#1)Initialisation of lattice
#Gx,Gy,Gz=SARW(spin,N)
Gx=[300, 300, 300, 299, 299, 298, 297, 297, 298, 299, 299, 299, 299, 298, 298, 298, 297, 297, 297, 297, 298, 298, 298, 298, 298, 297, 297, 297, 297, 297, 297, 298, 298, 299, 300, 300, 300, 299, 299, 299, 300, 300, 299, 299, 299, 300, 300, 300, 300, 300, 300, 300, 300, 299, 299, 298, 297, 297, 298, 299, 299, 299, 299, 298, 298, 298, 297, 297, 297, 297, 298, 298, 298, 298, 298, 297, 297, 297, 297, 297, 297, 298, 298, 299, 300, 300, 300, 299, 299, 299, 300, 300, 299, 299, 299, 300, 300, 300, 300, 300]
Gy=[300, 301, 302, 302, 301, 301, 301, 300, 300, 300, 300, 300, 300, 300, 301, 302, 302, 302, 302, 302, 302, 302, 302, 301, 300, 300, 300, 301, 301, 301, 300, 300, 301, 301, 301, 302, 303, 303, 302, 302, 302, 301, 301, 301, 302, 302, 301, 300, 300, 300, 300, 301, 302, 302, 301, 301, 301, 300, 300, 300, 300, 300, 300, 300, 301, 302, 302, 302, 302, 302, 302, 302, 302, 301, 300, 300, 300, 301, 301, 301, 300, 300, 301, 301, 301, 302, 303, 303, 302, 302, 302, 301, 301, 301, 302, 302, 301, 300, 300, 300]
Gz=[300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 299, 298, 297, 297, 297, 297, 297, 298, 299, 300, 300, 299, 298, 298, 298, 298, 297, 297, 298, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 298, 298, 298, 298, 297, 297, 297, 297, 297, 298, 299, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 299, 298, 297, 297, 297, 297, 297, 298, 299, 300, 300, 299, 298, 298, 298, 298, 297, 297, 298, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 298, 298, 298, 298, 297, 297, 297, 297, 297, 298, 299]
for p in range(50):
spin[Gx[p],Gy[p],Gz[p]]=1
E1=Energy(Gx,Gy,Gz,spin)
print "Initial energy of system is",E1
f1=open("Initial_Data.txt",'w')
for i in range(len(Gx)):
f1.write("%d %d %d \n"%(Gx[i],Gy[i],Gz[i]))
f1.close()
#2) Matrices and terms required
Ener=(arange(59)-58).tolist() #List of energy values
E0=-58 #GRound state
lngE=zeros(len(Ener),dtype=float) #LogG
Hist=zeros(len(Ener),dtype=float)
lnf=1.0
#3)The WLA
for time in range(Niter):
i2=0
while i2 < L:
#E1=Energy(Gx,Gy,Gz,spin)
Gx1,Gy1,Gz1=Transform(Gx,Gy,Gz,spin) #Attempting a random move
E2=Energy(Gx1,Gy1,Gz1,spin) #Energy calculation of changed configuration
P = exp(lngE[E1-E0]-lngE[E2-E0]) #Acceptance probability
if P > uniform(0,1):
Gx,Gy,Gz=Equality(Gx1,Gy1,Gz1)
print 'Ok', Gx[0],Gy[0],Gz[0],E1,E2,time,i2
E1=E2
else:
spin[Gx1[0],Gy1[0],Gz1[0]]=0
spin[Gx[49],Gy[49],Gz[49]]=1
print 'Not Ok',Gx[0],Gy[0],Gz[0],E1,E2,time,i2
Hist[E1-E0] += 1.0
lngE[E1-E0] += lnf
i2=i2+1
if time % 1000 == 0:
Ha = sum(Hist)/(len(Hist))
Hmin = min(Hist)
if Hmin > 0.8*Ha:
print time,'Histogram is flat', Hmin, Ha, 'f=',exp(lnf),'lnf=',lnf
Hist=zeros(len(Hist))
lnf=lnf/2.0
if abs(lnf-0.0) < 0.00000001:
break
else:
print time,'Not flat',Hmin, Ha, 'f=',exp(lnf),'lnf=',lnf
f=open("Final_Data.txt",'w')
for i5 in range(len(lngE)):
f.write("%f %f \n"%(Ener[i5],lngE[i5]))
f.close()
下面是代码 "spinfun.py",其中有上述代码中使用的函数。
from scipy import *
import sys
import numpy as np
from pylab import *
spin=zeros((50,50,50), dtype=int)
Gx2=[25,25,25,24,24,23,22,22,23,24,24,24,24,23,23,23,22,22,22,22,23,23,23,23,23,22,22,22,22,22,22,23,23,24,25,25,25,24,24,24,25,25,24,24,24,25,25,25,25,25]
Gy2=[25,26,27,27,26,26,26,25,25,25,25,25,25,25,26,27,27,27,27,27,27,27,27,26,25,25,25,26,26,26,25,25,26,26,26,27,28,28,27,27,27,26,26,26,27,27,26,25,25,25]
Gz2=[25,25,25,25,25,25,25,25,25,25,24,23,22,22,22,22,22,23,24,25,25,24,23,23,23,23,22,22,23,24,24,24,24,24,24,24,24,24,24,23,23,23,23,22,22,22,22,22,23,24]
#A,B,C=np.loadtxt("Self2_trials.txt",usecols=(0,1,2),unpack=True,dtype=int)
#########
def SARW(spin,N):
g2=1
g1=0
i=N/2;j=N/2;k=N/2
Gx=[N/2];Gy=[N/2];Gz=[N/2]
spin[N/2,N/2,N/2]=1
while g2 < 50:
h=uniform(0,1)
if 0.0 <= h <= 0.167:
k=k+1
elif 0.167 <= h <= 0.334:
j=j+1
elif 0.334 <= h <= 0.501:
i=i+1
elif 0.501 <= h <= 0.668:
i=i-1
elif 0.668 <= h <= 0.835:
j=j-1
else:
k=k-1
if spin[i,j,k] == 0:
print 'Ok',i,j,k,h,g2
spin[i,j,k]=1
Gx=Gx+[i]
Gy=Gy+[j]
Gz=Gz+[k]
g2=g2+1
else:
print 'Not Ok',i,j,k,h
if 0.0 <= h <= 0.167:
k=k-1
elif 0.167 <= h <= 0.334:
j=j-1
elif 0.334 <= h <= 0.501:
i=i-1
elif 0.501 <= h <= 0.668:
i=i+1
elif 0.668 <= h <= 0.835:
j=j+1
else:
k=k+1
g1=g1+1
return Gx,Gy,Gz
############
def Energy(Gx,Gy,Gz,spin):
S=0
Su=[]
for i in range(50):
i1=Gx[i]
j1=Gy[i]
k1=Gz[i]
n=spin[i1+1,j1,k1]+spin[i1-1,j1,k1]+spin[i1,j1+1,k1]+spin[i1,j1-1,k1]+spin[i1,j1,k1+1]+spin[i1,j1,k1-1]
S=S+n
Su=Su+[n]
E1=(S-98)/2
E=-E1
return E
###########
def Transform(Gx,Gy,Gz,spin):
Gx1=[];Gy1=[];Gz1=[]
m=0
while m < 50:
Gx1=Gx1+[Gx[m]]
Gy1=Gy1+[Gy[m]]
Gz1=Gz1+[Gz[m]]
m=m+1
i=Gx1[0];j=Gy1[0];k=Gz1[0]
g=0
g1=0
while g < 1:
h=uniform(0,1)
if 0.0 <= h <= 0.167:
k=k+1
elif 0.167 <= h <= 0.334:
j=j+1
elif 0.334 <= h <= 0.501:
i=i+1
elif 0.501 <= h <= 0.668:
i=i-1
elif 0.668 <= h <= 0.835:
j=j-1
else:
k=k-1
if spin[i,j,k] == 0:
spin[i,j,k]=1
spin[Gx1[49],Gy1[49],Gz1[49]]=0
for i1 in range(50):
n1=49-i1
if n1 != 0:
Gx1[n1]=Gx1[n1-1]
Gy1[n1]=Gy1[n1-1]
Gz1[n1]=Gz1[n1-1]
else:
Gx1[n1]=i;Gy1[n1]=j;Gz1[n1]=k
g=g+1
else:
if 0.0 <= h <= 0.167:
k=k-1
elif 0.167 <= h <= 0.334:
j=j-1
elif 0.334 <= h <= 0.501:
i=i-1
elif 0.501 <= h <= 0.668:
i=i+1
elif 0.668 <= h <= 0.835:
j=j+1
else:
k=k+1
g1=g1+1
return Gx1,Gy1,Gz1
########
def Equality(Gx,Gy,Gz):
Gx1=[];Gy1=[];Gz1=[]
for m in range(50):
Gx1=Gx1+[Gx[m]]
Gy1=Gy1+[Gy[m]]
Gz1=Gz1+[Gz[m]]
return Gx1,Gy1,Gz1
SO这里是我现在面临的问题。当我执行这段代码时,代码运行得很好,但在某一步突然停止。代码没有返回任何异常或错误,也没有终止,所以我必须杀死执行。
我搜索了一下答案,我试着用下面的命令来追踪代码的工作情况。
python -m trace --trace WL3D.py
上面一行很明显碰到了一堆语句打印出来,过了几行就开始执行代码了。这时它想用输入来测试代码。于是我给了必要的输入,它现在正在运行一个无限循环。
我无法追溯到是算法的哪一部分在无限循环中发送代码。有没有其他可能的方法来解决这个问题?非常感谢任何帮助。
P.S:我希望你在运行代码的时候添加以下细节。
输入MC的步数。你可以给任何你想要的整数。
输入单体数量:50(我写的这段代码是先对50个单体的聚合物进行计算)。
输入网格的尺寸。600 (您可以使用任何整数,但我发送的代码需要600。你可以使用任何整数,如果你注释第17-21行,取消注释第16行。)
这是一段相当复杂的代码,我也不太明白不同的部分应该做什么,但我很确定问题出在了 Transform
函数。如果你在 while 循环中添加一个计数器,你会发现有时候 g < 1
条件将一直为真,代码将永远不会退出循环。我注意到你先初始化然后再更新 g1
但你从来不用它 也许你忘了添加一些连接 g
和 g1
?