我编写了一个python脚本来执行对图形的覆盖,但是在小型图形(100个节点)上运行它需要一分钟以上的时间。
今天有人推荐cython来提高效率,所以我按照this guide修改我已有的代码。
运行python代码的结果如下:
In [6]: %timeit test.test()
1000 loops, best of 3: 1.88 ms per loop
遵循指南后,结果为:
In [7]: %timeit c_test.test()
1000 loops, best of 3: 1.05 ms per loop
性能较好,但我相信可以改进很多。鉴于我今天刚遇到cython,所以我想问你如何改善此代码:
import random as rnd
import numpy as np
cimport cython
cimport numpy as np
DTYPE = np.int
ctypedef np.int_t DTYPE_t
def choose_color(not_valid_colors, valid_colors):
possible_values = list(valid_colors - not_valid_colors)
if possible_values:
return rnd.choice(possible_values)
else:
return max(valid_colors.union(not_valid_colors)) + 1
@cython.boundscheck(False)
cdef np.ndarray[DTYPE_t, ndim=2] greedy_coloring(np.ndarray[DTYPE_t, ndim=2] distances, int num_nodes, int diameter):
cdef int i, lb, j
cdef np.ndarray[DTYPE_t, ndim=2] c = np.empty((num_nodes+1, diameter+2), dtype=DTYPE)
c.fill(-1)
# Matrix C will not use the 0 column and 0 row to
# let the algorithm look very similar to the paper
# pseudo-code
nodes = list(range(1, num_nodes+1))
rnd.shuffle(nodes)
c[nodes[0], :] = 0
# Algorithm
for i in nodes[1:]:
for lb in range(2, diameter+1):
not_valid_colors = set()
valid_colors = set()
for j in nodes[:i]:
if distances[i-1, j-1] >= lb:
not_valid_colors.add(c[j, lb])
else:
valid_colors.add(c[j, lb])
c[i, lb] = choose_color(not_valid_colors, valid_colors)
return c
def test():
distances = np.matrix('0 3 2 4 1 1; \
3 0 1 1 3 2; \
2 1 0 2 2 1; \
4 1 2 0 4 3; \
1 3 2 4 0 1; \
1 2 1 3 1 0')
c = greedy_coloring(distances, 6, 4)
最佳答案
在Cython中,随着在Cython函数中删除更多Python调用,您将获得更快的速度。
例如,浏览代码,您正在choose_color()
的嵌套循环内调用greedy_coloring()
。以及在函数内部定义的变量都应该输入。由于它将被重复调用,因此会带来很多开销。
您可以将cython
与-a
选项一起使用(例如cython -a file.pyx
)来生成带注释的html文件,该文件可以直观地显示代码的哪一部分正在进行Python调用(黄线)。这将有助于您改善Cython代码。
抱歉,缺少具体的指针-希望这会有所帮助。
关于python - 使用cython在图形上执行框覆盖,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33160102/