Python Don';我不知道如何用Cython优化代码
我是新尝试优化与cython,我需要一些帮助,因为我知道我可以优化更多,但我不知道如何 首先,我用C语言声明变量,但是很多变量都是对象,我不知道如何声明 然后我有一个类,在HTML中,每当代码想要得到一个类的对象时,我都能看到它的速度很慢,所以我也想对它进行优化,我不知道怎么做:(Python Don';我不知道如何用Cython优化代码,python,optimization,cython,cythonize,Python,Optimization,Cython,Cythonize,我是新尝试优化与cython,我需要一些帮助,因为我知道我可以优化更多,但我不知道如何 首先,我用C语言声明变量,但是很多变量都是对象,我不知道如何声明 然后我有一个类,在HTML中,每当代码想要得到一个类的对象时,我都能看到它的速度很慢,所以我也想对它进行优化,我不知道怎么做:( 导入数学 随机输入 def级城市: 定义初始化(self,city_name='NoName',posx=0,posy=0): self.name=城市名称 self.x=posx self.y=posy 定义城市之
导入数学
随机输入
def级城市:
定义初始化(self,city_name='NoName',posx=0,posy=0):
self.name=城市名称
self.x=posx
self.y=posy
定义城市之间的距离(对象C1、对象C2):
“”“计算两个城市之间的距离”“”
dx=C1.x-C2.x
dy=C1.y-C2.y
返回math.sqrt(dx*dx+dy*dy)
def从文件(str文件名)读取城市:
“”“从文本文件读取城市列表”“”
cdef列表城市=[]#空城列表
cdef列表R=[]
打开(文件名)作为文件:
对于文件中的行:
R=行。拆分()
Cities.append(City(R[0]、float(R[1])、float(R[2]))
回归城市
定义路径距离(对象城市):
“”“计算按顺序穿过所有城市的路径的总距离”“”
cdef int i=0
cdef双D=0
对于范围内的i(len(城市)):
D=D+城市之间的距离(城市[i],
城市[i+1如果i+10:
pos=接近(路径[-1],未访问)
追加路径(未访问[pos])
del notvisted[pos]
返回路径
如果名称=“\uuuuu main\uuuuuuuu”:
导入argparse作为arg
parser=arg.ArgumentParser(prog='ARGUMENTS',用法='%(prog)s[options]'))
parser.add_参数(“input”,type=str,help=“包含城市列表的文件”)
args=parser.parse_args()
ListOfCities=从文件(str(args.input))读取城市
GoodList=GoodPath(城市列表)
打印(“初始距离=”,路径距离(城市列表),
“良好距离=,路径距离(良好列表))
这是我在cythonize时从HTML中得到的:
任何帮助都将不胜感激
谢谢!您的算法的复杂性是
O(n^2)
(带有n
城市数)。事实上,您遍历了所有城市,并对每个城市再次迭代了大多数城市(O(n)
城市)。还要注意,项目删除是在O(n)中执行的算法
时间。可以使用更有效的O(n log n)
算法计算结果:
您可以在O(n logn)
time中构建一个结构,或者更具体地说,构建一个结构,然后在O(logn)中查找任何其他城市最近的城市
使用此结构的时间。此外,最好将未访问的
的类型更改为集
,而不是列表
,以避免缓慢删除列表项
除此之外,我建议您将对象
类型的变量替换为低级类型(例如double/int的数组或元组),以便Cython可以生成更快的C代码
请注意,您的方法通常找不到整体最短路径,甚至可能找不到非常小的路径。有,但它们更昂贵
import math
import random
def class City:
def __init__(self, city_name='NoName', posx=0, posy=0):
self.name = city_name
self.x = posx
self.y = posy
def distance_between_cities( object C1, object C2 ):
"""Compute distance between two cities"""
dx = C1.x - C2.x
dy = C1.y - C2.y
return math.sqrt( dx*dx + dy*dy )
def read_cities_from_file ( str filename ):
"""Read list of Cities from text file"""
cdef list Cities= [] # List of Empty Cities
cdef list R = []
with open(filename) as file:
for line in file:
R= line.split()
Cities.append ( City( R[0], float(R[1]), float(R[2]) ) )
return Cities
def path_distance( object Cities ):
"""Compute total distance of the path traversing all cities in order"""
cdef int i = 0
cdef double D = 0
for i in range( len(Cities) ):
D = D + distance_between_cities ( Cities[i],
Cities[i+1 if i+1<len(Cities) else 0])
return D
cdef int closerCity( object City, object Cities ):
"""Compute position of the city C in the list of Cities that is closer to City"""
cdef float minDist = 2*1000*1000
cdef int minIndex= 0
cdef int i = 0
cdef double dx = 0
cdef double dy = 0
cdef double dist = 0
for i in range(len(Cities)):
c = Cities[i]
dx = City.x - c.x
dy = City.y - c.y
dist = dx*dx + dy*dy
if dist < minDist:
minDist = dist
minIndex= i
return minIndex
def GoodPath( object Cities ):
"""Generate a path with small total distance using greedy algorithm"""
cdef list NotVisited = []
cdef int len_C = len(Cities)
cdef int i = 0
for i in range(len_C):
NotVisited.append(Cities[i])
Path= [ Cities[0] ] # Start path with first city
del NotVisited[0]
while len(NotVisited) > 0:
pos = closerCity( Path[-1], NotVisited )
Path.append( NotVisited[pos] )
del NotVisited[pos]
return Path
if __name__ == "__main__":
import argparse as arg
parser = arg.ArgumentParser(prog='ARGUMENTS', usage='%(prog)s [options]')
parser.add_argument("input", type=str, help="File containing list of Cities")
args = parser.parse_args()
ListOfCities= read_cities_from_file ( str(args.input) )
GoodList = GoodPath( ListOfCities )
print ( "Initial Distance =", path_distance( ListOfCities ),
" Good Distance =", path_distance( GoodList) )