4
\$\开始组\$

我正在编写一个程序,以在您应用考拉兹猜想算法。我想知道我应该改变什么,也想知道是否有一种方法可以看到哪个种子产生了特定的地块。我对颜色也有一些问题。

将matplotlib.pyplot导入为plt将numpy导入为npdef collatz(种子):“”“应用Collatz猜想算法,并在每次迭代后存储种子的所有值,以便稍后显示”“”y=[种子]当播种时!=1:如果种子%2==0:种子=种子/2其他:种子=(3*种子)+1y.append(种子)返回y颜色=plt.cm.bwr(np.linspace(0,11500))对于范围(11500)中的i:#通过将算法应用于特定的种子集来收集数据Y=collatz(i)plt.plot(Y,颜色=颜色[i])plt.title(“科拉茨猜想”)plt.xlabel(“卡住之前的迭代次数”)plt.ylabel(“达到值”)展示()
\$\端组\$
2

3个答案

重置为默认值
6
\$\开始组\$

请注意您如何手动重复种子数(1500):

颜色=plt.cm.bwr(np.linspace(0,11500))对于范围(11500)内的i:...

这总是一个好兆头,它应该是一个变量。

一种选择是将绘图代码放入由参数化的函数中n种子(然后添加1以使命名准确):

定义plot_collatz(n_seeds=1500):#                ------------“”“为给定数量的种子绘制Collatz序列”“”颜色=plt.cm.bwr(np.linspace(0,1,n种子+1))#                                     ---------对于范围(1,n种子+1)内的种子:#                    ---------plt.plot(collatz(种子),颜色=颜色[种子])plt.title(“科拉茨猜想”)plt.xlabel(“卡住之前的迭代次数”)plt.ylabel(“达到的值”)展示()plot_collatz(10)

plot_collatz(10)输出

\$\端组\$
6
  • \$\开始组\$ 你不是掉进了自己的陷阱吗n种子+1两次?为什么不将此作为另一个变量?:) \$\端组\$
    – 无穷零
    5月1日6:53
  • \$\开始组\$ 这取决于“陷阱”是什么初学者综上所述,我认为最重要的是,如果我们想改变种子数量,现在我们只需要做一次。该外卖信息不受多个n种子+1(如果我们要解决后者,我不建议为n种子+1). \$\端组\$ 5月1日11:14
  • \$\开始组\$ @nocomment此图是plot_collatz(10)(前面的代码块),因此它不包含种子1161。如果你对更高的种子感兴趣,这个数字会变得很忙,但以下是1500个序列的版本. \$\端组\$ 5月2日1:52
  • \$\开始组\$ @正如上面的答案所说,这个图背后的主要思想是显示如果应用算法,某些种子的行为。是的,看到哪个种子产生了特定的情节并不是很好,但我认为它很好地显示了序列的混乱程度。也许与散点图搭配会更有意义 \$\端组\$
    – 洛伦佐
    5月2日4:54
  • \$\开始组\$ @是的,我很怀念你改变了这一点。你为什么这么做? \$\端组\$ 5月2日7:04
4
\$\开始组\$

整数算术

种子=种子/2取值为种子(最初是一个整数),然后将其除以2,并将结果存储为浮动返回种子.

>>> 10 / 25

如果collatz序列值超过\$2^{53}\$,种子%2==0由于有限的浮动精确度。

>>>2**53+1.0#你会觉得这很奇怪,但事实并非如此!9007199254740992

相反,您应该使用整数除法:种子=种子//2.Python的整数具有可变长度表示,因此可以轻松精确地保存非常大的整数值。

您还可以使用增强型工作分配操作员在这里(种子//=2). 它节省了键入变量名的额外时间,并且--当左手端比简单变量更复杂时,例如自给种子a[i]--避免再次评估术语,这可能会加快速度。

\$\端组\$
11
  • \$\开始组\$ 谢谢你的建议。所以我应该只在复杂的情况下使用这个“契约形式”,对吗?另外,我不明白2^53怎么可能导致错误:只有一个浮点数(0) \$\端组\$
    – 洛伦佐
    5月1日20:00
  • \$\开始组\$ @洛伦佐我可能会用//=也从这里开始。输入/维护更少,这是人们通常的做法。只有在核心微优化时,我才避免使用int。 \$\端组\$ 5月1日20:04
  • \$\开始组\$ 好的,它使代码更加可读,双//使我不会存储无用的浮点数字。这会使程序更快吗? \$\端组\$
    – 洛伦佐
    5月1日20:08
  • \$\开始组\$ @洛伦佐实际上//而不是/可能会成功更慢的。因为整型数往往比浮点数慢,因为需要处理它们的任意大小。你可以测量一下。但是。。。你真的应该使用int。否则你可能会得到错误的结果! \$\端组\$ 5月1日20:14
  • 1
    \$\开始组\$ @AJNeufeld Btw这是我的基准对于我提到的27对29纳秒。 \$\端组\$ 5月1日22:03
\$\开始组\$

标识符

文献倾向于谈论产生的“价值观”\3亿美元+1\$过程。“种子”用于启动过程,我们看到连续的值从那里增长。接受种子参数。但在增长循环期间,请使用另一个名称,也许n个.

注释

指出我们接受也无妨种子:int,因为变量rational过程可能会执行a上的冰雹作业种子:分数.(尽管我承认缺乏从分数导入分数在这里是一种提示。)

它还将为您设置一个麻木JIT装饰器。

单一责任

谢谢你提供了这个漂亮的文档字符串。

def collatz(种子):“”“应用Collatz猜想算法,并在每次迭代后存储种子的所有值,以便稍后显示”“”

它简洁准确。它还帮助我们看到我们正在做什么

  1. 计算
  2. 商店

考虑把重点放在计算上,所以存储是别人的问题。

通过键入import Generatordef collatz(seed:int)->生成器[int,None,None]:“”“生成冰雹值。”“”n=种子当n>1时:如果n%2:n=3*n+1其他:n//=2产量ndef main(num_seeds:int=1500)->无:...对于范围(1,num_seeds+1)中的种子:y=列表(collatz(种子))...

彩色地图

这个厘米.bwr彩色地图很漂亮。你可以考虑玩循环的,循环的彩色地图,突出混沌非线性您绘制的数据的性质。或者循环浏览分类图。

您可能会发现绘制点而不是线,并使用部分透明的beta版,允许您实现更高的可视数据密度。

缓存

如果将给定种子概括为生产一个(迭代次数,最大值)元组,您可能会找到@lrucache或@高速缓存装饰师要有帮助;或者引入您自己的缓存数组。这个文学有时使用延迟描述迭代次数对于给定的种子。Leavens和Vermeulen1992年在这个领域做了一些有趣的工作。

当然,我们正在进行的计算是所以当时很轻花在缓存检查上的时间可能会占用计算时间。所以我们想展开有点,也许通过做半打“普通”函数调用,然后是检查缓存的函数调用。或者等效地,处理每七粒种子,进行模同余到零检验。或者使用更大的素数。

\$\端组\$
6
  • \$\开始组\$ 谢谢你详尽的回答。循环颜色图不会“隐藏”算法的混乱吗?我认为非循环颜色图更容易估计种子:小种子=蓝色,大种子=红色(显然与所选间隔有关)。顺便说一下,这是我的第一个matplotlib程序,>我还在学习python的基础知识,所以我真的不知道如何检查缓存。 \$\端组\$
    – 洛伦佐
    5月1日20:16
  • \$\开始组\$ 好,塔夫特告诉我们,有不止一个感知通道可以访问视觉皮层,而且这个皮层擅长于不止一件事。这一切都取决于你想要突出显示的潜在数据的哪一方面。 \$\端组\$
    – J_小时
    5月1日20:30
  • \$\开始组\$ 关于缓存:在dict中查找int也很快,特别是当它们像这里一样密集时。顺便说一句,如果缓存实际上没有帮助,那么另一个想法是:他们已经在使用NumPy。我们可以并行运行所有种子。将它们放在一个数组中,然后对所有它们执行一个步骤,然后过滤出1。直到没有留下。这可能会很有竞争力/很有趣。 \$\端组\$ 5月1日20:40
  • \$\开始组\$ cPython字典实现令人印象深刻,但对于当前的“密集”情况,它不可能与阵列访问竞争,因为它必须做更多的工作。//并行运行所有种子当然有一些魅力。加油!创建实施,发布答案;我会投赞成票。 \$\端组\$
    – J_小时
    5月1日21:34
  • \$\开始组\$ 哦,我没有将它与数组(或列表?)访问进行比较。我说的是你的最后一段,听起来用dict缓存可能会让他们的代码变慢。虽然使用数组/列表缓存,但您可能需要提前知道峰值,或者始终检查是否要扩展它,这可能比dict访问成本更高。我已经完成了NumPy版本,它确实更快了,但我认为它不适合在这里作为答案。我会在下一条评论中添加链接。 \$\端组\$ 5月1日21:47

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.