Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.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 如何将N体模拟录制为视频?_Python_Pygame_Simulation - Fatal编程技术网

Python 如何将N体模拟录制为视频?

Python 如何将N体模拟录制为视频?,python,pygame,simulation,Python,Pygame,Simulation,我已经用Python中的Barnes Hut优化实现了一个N体模拟,对于N=10000个体,它的运行速度不是不可接受的,但它仍然太慢,无法实时观看 每个时间步都会生成一个新的帧,要显示该帧,我们必须首先计算实体的新位置,然后将它们全部绘制出来。对于N=10000,生成一帧大约需要5秒(这太高了,因为Barnes Hut应该能提供更好的结果)。通过pygame模块进行显示 因此,我想记录我的模拟,并在以更高的速度完成后重放一次 如何在不降低程序速度或不超过内存限制的情况下完成此操作? 一个可能的解

我已经用Python中的Barnes Hut优化实现了一个N体模拟,对于N=10000个体,它的运行速度不是不可接受的,但它仍然太慢,无法实时观看

每个时间步都会生成一个新的帧,要显示该帧,我们必须首先计算实体的新位置,然后将它们全部绘制出来。对于N=10000,生成一帧大约需要5秒(这太高了,因为Barnes Hut应该能提供更好的结果)。通过pygame模块进行显示

因此,我想记录我的模拟,并在以更高的速度完成后重放一次

如何在不降低程序速度或不超过内存限制的情况下完成此操作?

一个可能的解决方案是简单地每次保存pygame屏幕,但这显然非常缓慢


我还考虑存储每个时间步生成的身体位置列表,然后在情况结束后重新绘制所有帧。绘制框架仍然需要一些时间,但没有计算新位置所需的时间多。

您将纯python与调用编译代码的各种程序进行比较。纯python比优化编译器生成的代码慢几个数量级。撇开语言战争不谈,有些情况下python对脚本语言的执行速度非常快,有些情况下它的执行速度非常慢

我所做的许多要求很高的python项目都需要使用
numpy/pandas/scipy
,或者像Pypy这样的解释器来编译一些python代码,以便立即提高它们的执行速度。编译器倾向于生成更快的代码,因为它们可以脱机执行优化,而不是在运行时的时间压力下执行优化


视频文件是最通用、最易于管理的播放格式,但确实需要一些粘合代码。要制作一个,您需要一个库来将可视化帧编码为视频帧。似乎您已经能够生成每帧的图像,所以剩下的唯一一步就是找到视频编解码器

可以通过其命令行接口调用FFMPEG,将帧转储到视频文件中:

编写的示例代码是:

command = [ FFMPEG_BIN,
        '-y', # (optional) overwrite output file if it exists
        '-f', 'rawvideo',
        '-vcodec','rawvideo',
        '-s', '420x360', # size of one frame
        '-pix_fmt', 'rgb24',
        '-r', '24', # frames per second
        '-i', '-', # The imput comes from a pipe
        '-an', # Tells FFMPEG not to expect any audio
        '-vcodec', 'mpeg'",
        'my_output_videofile.mp4' ]

pipe = sp.Popen( command, stdin=sp.PIPE, stderr=sp.PIPE)
如果使用numpy阵列,则可以使用此命令转储帧:

pipe.proc.stdin.write( image_array.tostring() )
这个方法已经被库包装好了


还有一个简单的选择,但它牺牲了视频文件的多功能性(以及真正令人印象深刻的有损压缩算法)。生成可视化帧时将其转储到文件中。修改可视化工具以从文件中读取帧并以指定速率播放

这是一种简单的方法,我过去使用过它来保存重播数据,以便在我玩多人机器人游戏时观看



应该特别提到备忘录,它非常适合数学计算。只需缓存递归定义的函数的结果,就可以节省大量不必要的计算,只需占用少量内存。Barnes Hut似乎有一个递归的方面,所以你应该检查记忆该部分的可能性。

没有真正的联系,但你为什么认为“(这太高了,因为Barnes Hut应该会给出更好的结果)”@juanpa.arrivillaga:在比较了运行时和天真的直接O(N^2)算法之后,我验证了Barnes Hut确实按照预期在O(NlogN)中工作。N=10000甚至不能直接比较。然而,我在网上看到过其他Barnes Hut实现,对于N=10000,每帧只需要0.5秒。我还没有确定缓慢的根源,但我确信我的代码可以比现在快10倍?或者其他一些语言,或者他们可能使用一个数字计算包,比如
numpy
?@juanpa.arrivillaga:不,我不相信它们通常使用python。我看到的一个模拟市民是用C++编写的。我想知道python或pygame是否很慢。我也在用numpy。让我澄清一下,我所看到的快速SIMS是在标准PC上实时运行的,这意味着没有PARRALLIAL化或特殊的GPU。嗯,我不希望Python实现能像C或C++实现那样快,特别是对于这种问题。事实上,我对Python的执行速度比C++执行速度慢10倍的印象非常深刻。