猫史档案馆


【Python求助】能帮我优化一下这个程序吗?

用户:Planet_CubePlanet_Cube查看:0 回复:0 评论:0 创建时间:2024-01-27T22:14:51


我写了一个计算量子波函数的程序(虽然和量子力学有关,但是不要怕,本质上就是一堆计算),代码如下: fromPILimportImage,ImageDraw importmath '''这是一个处理波函数图像的程序 输入初始波函数图像,它会给你一段时间后的图像 红色分量表示振幅,绿色分量表示波高,蓝色分量表示相位''' defvector_addition(m1,f1,m2,f2): #向量相加运算 h1=m1*math.cos(f1) v1=m1*math.sin(f1) h2=m2*math.cos(f2) v2=m2*math.sin(f2) h=h1+h2 v=v1喵2 length=math.sqrt(h**2喵**2) ifh>0: angle=math.atan(v/h) elifh<0: angle=math.atan(v/h)+math.radians(180) elifh==0andv>0: angle=math.radians(90) elifh==0andv<0: angle=math.radians(270) else: angle=0 returnlength,angle defcalculate_wave(imgobj,time,scale,mode="all"): w=int(imgobj.width) h=int(imgobj.height) image=imgobj.resize((w,h)) ifmode=="all": image_new=Image.new('RGB',(w,h),(0,0,0)) else: image_new=Image.new('L',(w,h),0) draw=ImageDraw.Draw(image_new) origin_wave=[] #此循环用于读取图片中的信息 foryinrange(h): forxinrange(w): pos=(x,y) pixel=image.getpixel(pos) r=pixel[0] b=pixel[2] ifr!=0orb!=0: origin_wave.append((r,b,x,y)) #此循环用于生成新图片 foryinrange(h): print(y,'row(s)hadbeencompleted')#实时打印生成情况 forxinrange(w): r=0 b=0 foriinorigin_wave: """每个像素都相当于波源,它们都各自给此位置传播一个波,所有的波相加得到此位置的新波 波的相加遵循向量运算法则,波在传播过程时的相位(即向量的辐角)发生改变,增量为m*d^2/t 其中m表示质量(此函数默认质量为1,故省去),d^2表示距离的平方,t表示时间 此处增加了scale变量以表示图像的缩放,不过其作用于质量类似。角采用弧度制表示""" r,b=vector_addition(r,b,i[0], math.radians(i[1]/256*360)+( (i[2]-x)**2+(i[3]-y)**2) *scale/time) r/=len(origin_wave) g=r*math.sin(b) r=r**2#在某处找到粒子的可能性是振幅的平方 ifmode=="all": draw.point(xy=(x,y), fill=(math.floor(r),math.floor(g),math.floor(b/math.radians( 360)*256))) elifmode=="red": draw.point(xy=(x,y),fill=math.floor(r)) elifmode=="green": draw.point(xy=(x,y),fill=math.floor(g)) elifmode=="blue": draw.point(xy=(x,y),fill=math.floor(b/math.radians(360)*256)) returnimage_new img=Image.open(r"test_waveL.png") calculate_wave(img,5,0.1,"red").save('new1L_red.jpg') 输入一张这样的图片:(名称为“test_waveL”,格式为PNG,如果你想亲自尝试的话记得把它和代码保存在同一个文件夹里面) 你将会得到这个:(格式为JPG) 一个地方颜色越浅,在此找到这个粒子的概率越高 可以看到确实像波一样扩散出去了,nice 但是这个程序面临一个很严重的问题:性能。就是这样一张100*100的图片,花了我5秒的时间。为什么会这样呢?我们看这段代码: foryinrange(h): forxinrange(w): pos=(x,y) pixel=image.getpixel(pos) r=pixel[0] b=pixel[2] ifr!=0orb!=0: origin_wave.append((r,b,x,y)) #此循环用于生成新图片 foryinrange(h): print(y,'row(s)hadbeencompleted')#实时打印生成情况 forxinrange(w): r=0 b=0 foriinorigin_wave: """每个像素都相当于波源,它们都各自给此位置传播一个波,所有的波相加得到此位置的新波 波的相加遵循向量运算法则,波在传播过程时的相位(即向量的辐角)发生改变,增量为m*d^2/t 其中m表示质量(此函数默认质量为1,故省去),d^2表示距离的平方,t表示时间 此处增加了scale变量以表示图像的缩放,不过其作用于质量类似。角采用弧度制表示""" r,b=vector_addition(r,b,i[0],math.radians(i[1]/256*360)+(i[2]-x)**2+(i[3]-y)**2)*scale/time) r/=len(origin_wave) g=r*math.sin(b) r=r**2#在某处找到粒子的可能性是振幅的平方 ifmode=="all": draw.point(xy=(x,y), fill=(math.floor(r),math.floor(g),math.floor(b/math.radians(360)*256))) 它用到了一个2层循环,一个3层循环,循环次数和图片尺寸成正比,而且那个3层循环的本质实际上是2层套上前面的2层,也就是4层循环,时间复杂度达到了n^4,也就是说,一张100*100的图片,需要循环1亿次。我的电脑性能比较差,喵U频率还不到1GHz,不卡才怪 但是我实在不知道该怎么办了,请各位懂Python的大佬们帮忙优化一下,我将不胜感激imgsrc="https://static.codemao.cn/emoji/codemao/%E7%BC%96%E7%A8%8B%E7%8C%AB_%E5%8A%A0%E6%B2%B9.gif"alt="emotion_编程猫_加油"  


回复

上一页1 页 / 共 0下一页