You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Runge-Kutta法模拟Lorenz吸引子异常:变量演化后趋稳停滞求助

Lorenz吸引子RK4模拟停滞问题排查

我尝试用Runge-Kutta4方法模拟Lorenz吸引子,但未得到预期结果:系统先演化一段时间,随后所有变量变为常数,演化停滞。我模拟了多个粒子,初始条件通过伪随机生成器在0到1之间生成,以下是编写的代码,恳请帮忙排查问题。

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>

#define N 1000000
#define Nt 3
#define fran rand()/((double)RAND_MAX+1)

double h,s,r,b;

void rk4(double *x, double *y, double *z);
double fx(double x,double y,double z);
double fy(double x,double y,double z);
double fz(double x,double y,double z);


int main()
{
    double x[Nt], y[Nt], z[Nt];
    int i,j;
    FILE *f;
    char name[20]="Lorenz.txt";
    srand(time(NULL));

    f = fopen(name,"w");
    h = 0.01;
    s = 10.0;
    r = 18.0;
    b = 8.0/3.0;

    for(i=0;i<Nt;i++)
    {
        x[i] = fran;
        y[i] = fran;
        z[i] = fran;
    }

    if (f==NULL) return 1;

    for(i=0;i<N;i++)
    {
        rk4(x,y,z);

        for(j=0;j<Nt;j++)
        {
            fprintf(f,"%lf\t%lf\t%lf\t%lf\t",h*i,x[j],y[j],z[j]);
        }

        fprintf(f,"\n");
    }

    fclose(f);

}

double fx(double x,double y,double z)
{
    return s * (y - x);
}

double fy(double x,double y,double z)
{
    return x * (r - z) - y;
}

double fz(double x,double y,double z)
{
    return x * y - b * z;
}


void rk4(double *x, double *y, double *z)
{
    int i;
    double xn,yn,zn;
    double k1[3], k2[3], k3[3], k4[3];

    for(i=0;i<Nt;i++)
    {

        xn = x[i];
        yn = y[i];
        zn = z[i];

        k1[0] = h * fx(xn,yn,zn);
        k1[1] = h * fy(xn,yn,zn);
        k1[2] = h * fz(xn,yn,zn);
        k2[0] = h * fx(xn+0.5*k1[0],yn+0.5*k1[1],zn+0.5*k1[2]);
        k2[1] = h * fy(xn+0.5*k1[0],yn+0.5*k1[1],zn+k1[2]*0.5);
        k2[2] = h * fz(xn+0.5*k1[0],yn+0.5*k1[1],zn+k1[2]*0.5);
        k3[0] = h * fx(xn+0.5*k2[0],yn+0.5*k2[1],zn+k2[2]*0.5);
        k3[1] = h * fy(xn+0.5*k2[0],yn+0.5*k2[1],zn+k2[2]*0.5);
        k3[2] = h * fz(xn+0.5*k2[0],yn+0.5*k2[1],zn+k2[2]*0.5);
        k4[0] = h * fx(xn+k3[0],yn+k3[1],zn+k3[2]);
        k4[1] = h * fy(xn+k3[0],yn+k3[1],zn+k3[2]);
        k4[2] = h * fz(xn+k3[0],yn+k3[1],zn+k3[2]);

        x[i] = xn + (k1[0]+2*k2[0]+2*k3[0]+k4[0])/6.0;
        y[i] = yn + (k1[1]+2*k2[1]+2*k3[1]+k4[1])/6.0;
        z[i] = zn + (k1[2]+2*k2[2]+2*k3[2]+k4[2])/6.0;

    }
}

问题排查与解决

核心原因:参数选择导致系统收敛到不动点

Lorenz系统的行为由参数s、r、b决定:

  • 当r < 24.74时,系统会收敛到稳定的不动点,不会出现混沌的吸引子行为。你当前设置的r=18.0正处于这个区间,所以粒子演化一段时间后会停在不动点,变量不再变化。

修复方案

将参数r修改为经典的混沌阈值以上的值,比如r=28.0(这是Lorenz吸引子的标准参数之一):

r = 28.0;

修改后重新运行代码,就能观察到粒子在混沌吸引子上的演化轨迹,不会再出现停滞现象。

代码其他细节验证

  • 随机数生成:fran的定义rand()/((double)RAND_MAX+1)正确,能生成0到1之间的均匀分布随机数。
  • RK4实现:四阶龙格-库塔的k1~k4计算步骤、状态更新公式均符合标准,代码逻辑无错误。
  • 文件输出:每次迭代输出所有粒子的时间步和状态,格式正常。

内容的提问来源于stack exchange,提问作者Ander Gabarrus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 02:25:55