我刚开始尝试使用cython进行优化,因此我需要一些帮助,因为我知道我可以进行更多优化,但是我不知道该怎么做。
首先,我在C中声明了变量,但是其中很多是对象,我不知道如何声明。
然后我有了该类,在HTML中,每次代码想要获取该类的对象时,我都可以看到它很慢,因此我也想对其进行优化,而且我不知道该怎么做:(
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) )
这是我进行cythonize时从HTML中获得的内容: Part 1 of the HTML Part 2
任何帮助将不胜感激
谢谢!
答案 0 :(得分:0)
算法的复杂度为 O(n^2)
(城市为n
)。实际上,您会遍历所有城市,并针对每个城市再次遍历大多数城市(O(n)
个城市)。另请注意,项目删除是在O(n)
时间内进行的。可以使用更有效的 O(n log n)
算法来计算结果:
您可以在O(n log n)
时间建立K-d tree结构,或更具体地说,建立Quad-tree结构,然后在O(log n)
时间找到其他任何城市的最近城市结构体。另外,最好将NotVisited
的类型更改为 set
而不是list
,以避免缓慢删除列表项。
除此之外,我建议您将object
类型的变量替换为较低级别的类型(例如,数组或double / int的元组),以便Cython可以生成更快的C代码。
请注意,您的方法通常找不到总的最短路径,甚至可能找不到非常小的路径。有better algorithms,但价格更高。