Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用python加速montecarlo代码 考虑从[0,t ]递增顺序给出的y点。我们要考虑这些点位于圆周上。现在考虑点x也来自[ 0,t ],并且也位于圆周T.圆周上。_Python_Optimization - Fatal编程技术网

用python加速montecarlo代码 考虑从[0,t ]递增顺序给出的y点。我们要考虑这些点位于圆周上。现在考虑点x也来自[ 0,t ],并且也位于圆周T.圆周上。

用python加速montecarlo代码 考虑从[0,t ]递增顺序给出的y点。我们要考虑这些点位于圆周上。现在考虑点x也来自[ 0,t ],并且也位于圆周T.圆周上。,python,optimization,Python,Optimization,我们说X和Y之间的距离是X中的每个点和Y中最近的点之间的绝对距离之和,这两个点都被认为位于一个圆中。将此距离写成Delta(X,Y) 我正试图找到一种快速的方法来近似计算X的所有可能旋转的圆之间的距离分布。我目前是通过蒙特卡罗模拟来实现这一点的。首先,这是我的代码来制作一些虚假数据 import random import numpy as np from bisect import bisect_left def simul(rate, T): time = np.random.ex

我们说X和Y之间的距离是X中的每个点和Y中最近的点之间的绝对距离之和,这两个点都被认为位于一个圆中。将此距离写成Delta(X,Y)

我正试图找到一种快速的方法来近似计算X的所有可能旋转的圆之间的距离分布。我目前是通过蒙特卡罗模拟来实现这一点的。首先,这是我的代码来制作一些虚假数据

import random
import numpy as np
from bisect import bisect_left

def simul(rate, T):
    time = np.random.exponential(rate)
    times = [0]
    newtime = times[-1]+time
    while (newtime < T):
        times.append(newtime)
        newtime = newtime+np.random.exponential(rate)
    return times[1:]
我们现在可以打印出任何我们喜欢的距离统计数据。我对方差特别感兴趣

print "Variance is ", np.var(dists)
不幸的是,我需要做很多,目前大约需要16秒。我觉得这有点令人惊讶,它是如此缓慢。任何关于如何加快它的建议,我都非常感激


编辑1。将迭代次数减少到100次(以前的值与我的计时不正确)。这现在在我的计算机上大约需要16秒


编辑2。修复了takeClosest中的bug

编辑:我刚刚注意到性能优化有点过早,因为表达式
最近的\u数-t
不是“圆”上距离的任何定义的有效实现,而“圆”上的距离仅是开放线上的距离

样本测试用例(伪代码):

请注意,圆
[0,10)
的定义意味着未定义
dist(0,10)
,但在极限范围内它接近0:
lim(dist(0,t),t->10)=0

圆上距离的正确实现是:

dist_of_t = min(t - closest_number_before_t,
                closes_number_after_t - t,
                T - t + closes_number_before_t,
                T - closest_number_after_t + t)

原始答复:

您可以在
timesY
上旋转和迭代,而不是
timesX
,因为该数组要小一个数量级-与迭代所有元素(
O(n)
)相比,对
timeX
进行左对分可以忽略不计(
O(logn)


但是我想,如果因为Python动态类型(每次尝试将其与其他值进行比较时,
timesX
中的~50000项中的每一项都必须检查其类型兼容性)=>将
timesX
timesY
转换为numpy数组应该会有所帮助,如果这不是足够的CPU加速的话(cython,numba,…)是您需要的功能
circle\u dist
可以用一个衬垫代替。因此,您可以将其插入外部
for i
循环:

sum(abs(最接近的(timesY,t)-t)表示时间x中的t)
此外,如果可能的话,您应该始终在一个步骤中分配像
dists
这样的数组,并避免多次追加元素

但是,不幸的是,这两项改进只节省了百分之几的计算时间

编辑1:
np.abs(…)
替换为
abs(…)
在我的机器上(在缩小的数据集上)将计算时间减少50%


编辑2:根据Aprillion的评论更新了一行程序。

你试过了吗?更适合这些类型的问题。@Aprillion感谢一个有趣的建议。谢谢。我希望在我走这条路线之前,他们可能会加快python/numpy/scipy的速度,因为numba的可移植性有问题。首先,您必须分析您的代码,以查看哪些操作的执行时间最长。嗯。
circle\u dist
is
O(n*logn)
我看不出有什么方法可以让算法更快-但是你可以尝试将
times
作为一个浮点数组,而不是动态类型的python数组..好主意。当切换
timesX
timesY
的速率时,看起来时间提高了90%左右。我不确定对r是否有任何影响结果。所以这取决于操作。我很高兴切换到numpy数组,但我无法切换比较顺序。你会得到一个完全不同的答案。只需切换到timesX=np.array(simul(1,t))timesY=np.array(simul(10,t))将时间加倍。然后从左对分更改为np.array将时间再增加50%…:(我不是
numpy
方面的专家,所以我不知道为什么这比纯Python慢。但是如果只是简单地切换顺序,你会得到不同的结果,你得到的结果不能定义为X和Y之间的
距离
——最多可以是“X到Y的距离”,而不是“在…和…”=>你确定你实现了正确的距离定义吗?对于这张图片,我使用了Excel饼图,其中包含3个系列
{3,3,4},{1,1,1,1,1,1,1,1},{4,2,4}
(看起来像甜甜圈的可以使用多个系列),编辑颜色(白色表示“透明”部分),删除所有标签,复制为图片并将其翻转(因此顶部的区域是连续的)并手动添加标签。您还可以使用生成器
sum(np.abs…
替换列表memory@Aprillion:噢,你的意思是
sum(abs(takeslestest(timesY,t)-t)表示timesX中的t)
?酷。我不知道这是可能的。:)
print "Variance is ", np.var(dists)
T = 10
X = [1, 2]
Y = [9]
dist(X, Y) = dist(1, 9) + dist(2, 9)
dist_on_line   = 8 + 7 = 15
dist_on_circle = 2 + 3 = 5
dist_of_t = min(t - closest_number_before_t,
                closes_number_after_t - t,
                T - t + closes_number_before_t,
                T - closest_number_after_t + t)