优化实根多项式生成函数以适配Desmos Aberth-Ehrlich求根实现演示的需求
嘿,我完全懂你现在的困扰——用随机生成的根构造多项式来演示Aberth-Ehrlich求根算法时,根挤在一起确实会让演示效果大打折扣,尤其是想展示算法如何精准定位每个根的时候。
先确认下你当前的实现逻辑,核心思路是没问题的:
设 $n \in \mathbb{Z}^+$ 为多项式次数,随机生成 $n$ 个满足 $-n \le r_i \le n$ 的实根 $r_0, r_1, \dots, r_{n-1}$,然后构造多项式 $p(z)=\prod_{i=1}^n(z-r_i)$
在Desmos里你用2n*random(n)-n来生成这些根,这个表达式确实能得到[-n,n]范围内的n个均匀随机数。
但正如你发现的,这种纯均匀随机的方式很容易出现根聚集的情况,尤其是当n比较大的时候,随机性会导致多个根挤在极小的范围内,既不直观,也不利于展示求根算法的迭代过程。
下面给你几个实用的改进方案,都是能直接在Desmos里实现的:
方法一:等间隔基准+小扰动
先在[-n,n]范围内均匀划分出n个固定间隔的基准点,再给每个点加一个小范围的随机偏移。这样既能保证根之间有基本的间距,又保留了一定的随机性,不会显得太规整。
Desmos代码实现:// 生成等间隔基准点(k从0到n-1) base = -n + 2n*(k)/(n-1) // 加入小扰动,扰动范围控制为间隔的1/5,避免根过度靠近 roots = base + (2n/(5*(n-1)))*random(n) - n/(5*(n-1))方法二:分层随机采样
把[-n,n]分成n个等宽的子区间,每个子区间内随机选一个根。这种方法能彻底杜绝根聚集的问题,每个根都分布在独立的“格子”里,非常适合展示算法如何逐个定位不同区域的根。
Desmos代码实现:// 每个子区间宽度为2n/n=2(k从0到n-1) interval_start = -n + 2*k roots = interval_start + 2*random(n)方法三:可控间距的递推随机根
如果想要更灵活的间距控制(比如让根的间距有自然变化但不会小于某个阈值),可以用递推的方式生成递增的随机序列,确保相邻根的间距大于你设定的最小值。
Desmos代码实现(利用列表递推功能):// 初始化第一个根 roots[1] = -n + 2n*random() // 递推生成后续根,d为最小间距(比如d=1,可根据n调整) roots[k] = roots[k-1] + d + (2n - (roots[k-1] + d) + n)*random() // k从2到n
最后给你两个演示小技巧:
- 可以给每个根对应的因式设置不同颜色,或者用彩色点标记根的位置,让观众更清晰地对应多项式和根的关系;
- 如果多项式函数值过大或过小导致图像显示异常,可以给多项式乘以一个小系数(比如0.1),让图像在坐标系里更舒展。
备注:内容来源于stack exchange,提问作者James Baw

