news 2026/9/9 4:30:28

基于阶跃函数脉冲控制的复杂网络同步图像加密Matlab仿真

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于阶跃函数脉冲控制的复杂网络同步图像加密Matlab仿真

图像加密、复杂网络同步、脉冲控制、阶跃函数,这四个词放一块儿,乍看很像一篇纯控制理论论文的标题。但把整条链路跑完就会发现,它其实是一条非常完整的信号处理流程:先让复杂网络在脉冲控制下收敛到同步状态,再从同步后的节点状态里提取混沌序列,把这段序列当作图像加密的密钥流;解密端再用完全相同的网络结构和参数,重新“复现”出同一段序列,从而把图像解回来。我照着这个思路在Matlab里完整仿真了一遍,中间踩了好几个坑,后面会逐个讲清楚。

这个方向最容易被低估的是“阶跃函数”这四个字。很多人一看到脉冲控制,第一反应是理想化的冲击信号,也就是数学上那个瞬间作用的脉冲。但在工程仿真里,真正能落在代码上的其实是阶跃函数构造的有限脉宽控制信号——在一小段时间内保持恒定输出,而不是数学意义上的无穷大幅值冲激。这个区别决定了整个数值求解怎么写,也决定了同步过程到底稳不稳定。这篇文章适合正在做复杂网络同步、混沌保密通信或者图像加密方向的研究生和工程师,尤其是那些已经看过论文理论、但不知道怎么把同步控制器和图像编解码真正耦合起来的朋友。

1. 复杂网络同步和图像加密是怎么搭上关系的

1.1 图像加密为什么需要一把“能复现的混沌钥匙”

图像这类数据有个天生弱点:相邻像素高度相关,灰度分布很不均匀,直接做简单替换或者固定置乱,很容易被统计分析识破。所以稍微像样一点的图像加密方案,基本都走“置乱加扩散”的路线:先把像素位置打乱,破坏空间相关性;再用一串伪随机序列去逐个修改像素值,把灰度分布抹平。

这里的关键就是那串伪随机序列从哪来。传统伪随机数发生器有周期,一旦被反向推导出种子,整个加密体系就崩了。混沌系统不一样,它对初值极敏感,初值差一点点,轨迹很快就分道扬镳,天然适合当密钥流的生成器。但混沌系统也带来一个麻烦:加密端生成的序列,解密端必须拿到一模一样的副本,否则解不出来。于是问题就变成了一个同步问题——接收端怎么让本地系统追上发送端的状态。这正是复杂网络同步理论能派上用场的地方。

1.2 复杂网络的优势不在“网”,而在高维状态空间

先说明一下,这里说的复杂网络不是互联网或者社交网络,而是动力学里常见的“节点加耦合”模型:一堆混沌振子互相连接,每个节点都有自己独立的非线性动力学,同时通过耦合矩阵互相影响。把这样一个网络作为混沌信号源,比单个Logistic映射或者单个Chen系统更有优势。

单个低维混沌系统的轨迹,理论上可以用相空间重构法反演,密钥空间有限,实际安全性是有隐患的。复杂网络的状态是多个混沌节点的联合演化,每个节点的维数叠在一起,整个状态空间维度远高于单个混沌系统。哪怕攻击者截获了某一个节点的时间序列,也很难还原整个网络的耦合结构,更别说推算出其他节点的状态。简单说,这就是从“一把锁”升级成了“一组联动的锁”,破解成本完全不是一个量级。

另外,网络规模的扩展性好。做图像加密时,一张256×256的灰度图就能提供65536个像素点,需要很长的密钥流。如果只有单个三维修混沌系统,密钥流本质上是同一条轨迹的不同分量,复杂度有限。用N个节点构成的网络,可以从多个节点、多个维度上取时间序列,还能混合成组合密钥,密钥流的熵密度明显更高。

1.3 脉冲控制和阶跃函数在链路里各干什么活

同步本身是个控制问题。最简单粗暴的做法是连续控制——每一时刻都对被控节点施加反馈,让它强行贴在目标轨道上。这个方法理论上好分析,但实现上很费劲。实际系统里,控制器、传感器、通信信道基本都是离散工作的,你不可能无时无刻都在给系统打信号,能量开销和通信负载都受不了。

脉冲控制的思路是:大部分时间让系统自由演化,只在离散的若干个时间点上给一次短促校正。就像开车,不是每时每刻都修正方向盘,而是每隔一段距离发现偏了,用力掰一下,然后继续让它跑。这样省力,而且天然契合数字控制器的采样节奏。

那阶跃函数出现在哪里呢?理想脉冲控制模型里,控制量是一个瞬间冲击,数学上方便,数值上却很尴尬——ode45这类求解器根本没法直接处理无穷大幅值。更常见的工程做法是:用阶跃函数把每个脉冲表示成一个“持续时间很短、幅值固定”的信号。阶跃函数本身并不神秘,本质就是那个熟悉的开关量,时间到了就跳变,保持一段时间,然后归零。用阶跃函数构造脉冲宽度可控的控制信号,仿真起来很顺畅,实际也能用模拟开关或者PWM电路实现。把理想冲击近似为“宽τ、幅值K”的阶跃信号,这就是标题里“基于阶跃函数”这个修饰语的工程含义。

2. 技术链路拆解:控制器设计与加解密流程

2.1 复杂网络动力学模型:先让节点跑起来

要把链路走通,第一步是建模。这里以最常见的同构复杂网络为例,网络中有N个节点,每个节点是一个三维混沌系统,比如Chen系统。第i个节点的完整动力学方程可以写成:

[ \dot{x}i(t) = f(x_i(t)) + c\sum{j=1}^{N} a_{ij} \Gamma x_j(t) + u_i(t) ]

其中(x_i(t))是第i个节点的状态向量,(f(\cdot))是非线性动力学项,c是耦合强度,(a_{ij})是网络拓扑矩阵的元素,(\Gamma)是内耦合矩阵,决定节点之间通过哪些状态分量互相影响,(u_i(t))是控制器输出。

每个节点内部的Chen系统写成标量方程组是:

[ \begin{cases} \dot{x}{i1} = a_c (x{i2} - x_{i1}) \ \dot{x}{i2} = (c_c - a_c)x{i1} - x_{i1}x_{i3} + c_c x_{i2} \ \dot{x}{i3} = x{i1}x_{i2} - b_c x_{i3} \end{cases} ]

参数通常取(a_c=35)、(b_c=3)、(c_c=28),这时候系统处于混沌状态。整个网络的状态向量直接拼成一个N×3维的大向量,Matlab里处理起来非常直接。

加密端和解密端各跑一个同样的网络。加密端的网络作为发送方,其中节点1被指定为参考轨道节点;解密端的网络作为接收方,本地节点在脉冲控制器作用下逐步追踪发送端节点1的轨迹。只要同步误差收敛到零,接收端本地节点的状态就和发送端完全一致,后续从这些状态里提取的混沌序列自然也能对齐。

2.2 同步控制器:用阶跃形式的脉冲量做离散校正

假设第1个节点是参考节点,从第2到第N个节点是需要同步的跟随节点。定义第i个节点的同步误差:

[ e_i(t) = x_i(t) - x_1(t) ]

控制目标是让所有跟随节点的误差收敛到零。这里采用定时间间隔的脉冲控制:每隔固定时间δ,采样一次误差,然后通过阶跃函数生成一段宽度为τ的控制信号。控制律可以写成:

[ u_i(t) = -K e_i(t_k) \cdot [H(t - t_k) - H(t - t_k - \tau)], \quad t \in [t_k, t_k + \tau) ]

其中(H(t))是Heaviside阶跃函数,(t_k)是第k次脉冲触发时刻,τ是阶跃信号的持续时间,K是控制增益。这个公式表达的意思很直白:在(t_k)时刻采样误差,然后在接下来τ这么长的一段时间里,把控制量维持在一个恒定的幅值上,τ结束立刻归零。把τ取得足够小,它就在行为上逼近理想脉冲,但数值上又完全可解。

为什么这种方式好?一方面是物理可实现。理想冲激不存在于现实执行器,但一个宽度几十毫秒的阶跃电压很常见。另一方面是便于用Lyapunov稳定性理论分析。可以证明,只要控制增益选得合适,使得“无控制区间内由系统非线性引起的误差增长”小于“脉冲时刻的控制衰减”,整个网络的同步误差就会指数收敛。设计时可以先算一个理论下界,再用仿真微调,后面第3节细说。

2.3 图像加解密总体流程:先建立全局视角

加密端流程并不复杂,但细节里全是坑。完整链路大概是下面这几步。

第一步,给定网络参数、节点初值、脉冲参数、耦合矩阵。第二步,用ode45跑完整同步过程,丢弃初始一段时间不稳定的瞬态。第三步,取同步收敛后参考节点和其他节点的状态序列,通过取小数位、放大、取模运算,量化成0到255的字节流。第四步,用其中一段字节流作为置乱密钥,生成像素位置索引;用另一段字节流作为扩散密钥,逐像素做XOR操作。第五步,得到密文图像。

解密端流程就是完全对称的逆过程。接收方网络通过脉冲控制锁定到发送方参考节点轨道后,用同样的方式生成密钥流,先做逆扩散,再做逆置乱,还原出明文图像。如果接收方网络没有同步好,哪怕密钥流只差一个字节,后面的图像几乎全是雪花噪点。这个特征也很适合用来判断你的同步到底成没成功——解密图像本身就是一个最直观的“示波器”。

3. 参数整定:为什么有的方案同步失败而有的成功

3.1 耦合强度与网络拓扑怎么选

同步能否建成,第一个关键参数是耦合强度c。我仿真时踩过最典型的一个坑就是c取得太小,控制器每两个脉冲之间的“自由演化段”里,节点之间的误差不降反增,等到下一发脉冲的时候已经偏出去太远,一个阶跃校正根本拽不回来。

耦合强度c的物理意义可以理解成“节点之间互相拉拢的力度”。c太小时,网络本质上趋于解耦,每个节点各自跑各自的混沌轨道,误差完全不收敛;c太大时,同步虽然容易实现,但所有节点状态高度一致,多节点联合密钥流本应具有的“多样性”就下降了,安全性反而变差。所以c不是越大越好,而是要在能同步的区间里,尽量保留节点间足够的动力学差异。经验做法是先从c=0.5开始试,观察误差曲线,如果收敛不了再往0.8到1.0附近调。

网络拓扑方面,加密端和解密端必须使用完全相同的耦合矩阵。否则它们的动力学不匹配,同步无从谈起。这里的建议是:仿真初期先用全连接网络验证链路,因为全连接矩阵对称、特征值好分析,等到基本功能跑通了,再换成更复杂的环形网络或者小世界网络来提升安全性。

3.2 脉冲间隔、脉宽和控制增益的经验区间

脉冲间隔δ、脉宽τ、控制增益K这三个参数是联合起作用的,不能单独拍脑袋。从控制频率的角度看,脉冲间隔δ如果太大,系统在两次脉冲之间自由演化过久,非线性混沌特性会让误差指数放大,控制器根本招架不住。如果δ太小,控制动作太频繁,能量消耗和连续控制差不多,失去了脉冲控制的意义。我用Chen系统仿真时的经验区间是δ取0.05到0.2秒,大致对应混沌系统基础周期的十分之一到五分之一。

控制增益K的调整是另一个高频踩坑点。K太小,每个脉冲周期的校正量不够,误差下降很慢甚至不降;K太大,单次校正过冲,系统可能直接发散。Matlab里做参数扫描时,可以先固定δ和τ,让K从2、4、8、16这样指数往上翻,看误差曲线怎么变化。一个比较实用的判断依据是:理想情况下,一次脉冲作用后误差应该下降一个数量级左右的量级变化,但又不能出现明显的振荡回弹。

脉宽τ用阶跃函数描述时,要始终小于脉冲间隔δ,通常取δ的十分之一到三分之一。如果τ太接近δ,控制信号几乎一直在作用,系统的行为会退化成连续控制,从能量角度看就不划算了。下表是我在测试过程中总结出来的调整方向,方便快速定位问题。

现象可能原因调整方向
误差完全不降c太小,耦合失效增大c到0.8以上
误差先降后震荡K过大,单次校正过冲减小K或者减小τ
误差缓慢下降但收敛太慢K偏小或者δ偏大增大K,或减小δ
系统数值发散溢出控制增益过大、参数积分步长过大降低K,改用更小步长
两脉冲之间误差急剧反弹δ太大把δ缩到原来的1/2再试

3.3 密钥空间怎么构造才够大

做图像加密,除了把图像解回来,还要考虑密钥安全。复杂网络同步系统天生就有很多“天然密钥参数”:所有节点的初始状态向量,每个分量都是实数,可以占64位甚至更多的信息量;耦合强度c、脉冲间隔δ、脉宽τ、控制增益K,每一个真实数值都能作为密钥的一部分;再加上耦合矩阵的网络结构,整个密钥空间的规模远超常规单混沌系统。

密钥空间的合理预估很简单,把每个连续参数的搜索精度当作有效位数,乘起来就够了。比如初值精度取1e-15,一个6维状态就有约90位二进制信息;再加上另外几个参数,轻轻松松超过2^100。对于图像加密而言,这个量级已经足够抵抗暴力穷举。

不过这里要提醒一句:密钥空间大不等于密钥流质量好。如果同步收敛后各节点状态高度相关,那从网络里取出的几路密钥流本质上可能是一路信号的线性组合,信息冗余会削弱安全性。所以取密钥流时,最好把不同节点的不同状态分量混合起来,或者对原始序列再做一次非线性变换,比如模加、位翻转、异或运算,打破节点间的线性关联。这个操作在代码层面只是多一行处理,但对最终图像密文的随机性贡献很大。

4. 基于Matlab的可复现实现

4.1 带脉冲的微分方程怎么解

Matlab里最常用的微分方程求解器是ode45,但它只能处理右端项随时间连续变化的系统。脉冲控制的核心动作是“在一个时刻施加状态跳变或阶跃信号”,直接丢给ode45会让求解器在断点处无效工作。正确做法是分段积分:把整个仿真时间切成很多小段,每一段就是一个脉冲周期;在每个周期内,用ode45积分一个周期长度的动力学;积分结束后,如果当前时刻需要施加控制,就手动修改状态向量,然后进入下一个小段继续积分。

这样处理既准确又直观,代码骨架如下。

% 参数初始化 N = 5; % 节点数 dim = 3; % 每个节点状态维数 T = 20; % 总仿真时间 delta = 0.1; % 脉冲间隔 pulse_width = 0.02; % 阶跃控制脉宽 K_gain = 10; % 控制增益 y = y0; % 初始状态 N*dim 维列向量 for k = 1:floor(T / delta) t0 = (k - 1) * delta; t1 = k * delta; % 积分当前脉冲区间 [~, Ysol] = ode45(@(t, x) network_rhs(t, x, params, y_ref), [t0, t1], y); y = Ysol(end, :)'; % 脉冲时刻施加阶跃校正 y = pulse_correction(y, K_gain, delta, pulse_width); % 记录同步误差 err_record(k) = compute_sync_error(y, y_ref, N, dim); end

注意网络右端项里要保留控制器输出。当仿真时间处于阶跃信号保持区间内,控制器输出为常数;一旦超过脉宽,控制器直接归零。这符合阶跃函数的语义。

4.2 网络右端项与脉冲校正模块

network_rhs函数是核心动力学。它做的事情很简单:外层循环遍历每个节点,计算自带的Chen系统非线性项;再遍历网络耦合项,把邻居节点状态对本节点的贡献累加上去。如果是接收端网络,还要把当前阶跃控制量加到对应节点上。关键代码如下:

function dydt = network_rhs(t, x, params) N = params.N; dim = params.dim; dydt = zeros(N * dim, 1); for i = 1:N idx_i = (i - 1) * dim + 1 : i * dim; xi = x(idx_i); dxi = chen_dynamics(xi, params.chen); % 网络耦合项 for j = 1:N if params.L(i, j) ~= 0 idx_j = (j - 1) * dim + 1 : j * dim; xj = x(idx_j); dxi = dxi + params.c * params.L(i, j) * params.Gamma * (xj - xi); end end % 控制器输出 dxi = dxi + control_input(t, idx_i, x, params); dydt(idx_i) = dxi; end end

control_input函数判断当前时间是否落在阶跃保持区间内。用Matlab写阶跃函数时有一个细节:很多人习惯写 t >= 0 来定义阶跃,但实际仿真里控制起点是 (t_k),所以要减去当前触发时刻再判断。整个控制律可以写成:

function u = control_input(t, idx_i, x, params) u = zeros(size(idx_i)); % 找到最近的脉冲触发时刻 tk = params.last_pulse_time; if t >= tk && t < tk + params.pulse_width e_hold = params.error_hold{params.node_id(i)}; u = -params.K * e_hold; end end

这里error_hold保存的是每个脉冲起点采样到的误差值。为什么要保存而不是实时用当前误差?因为真实控制器是采样保持的,无法连续获取误差信号。而且从理论上讲,阶跃函数控制律定义的就是“用t_k时刻的误差来控制整个脉宽区间”。这个细节非常重要,如果你在控制律里用了实时误差而不是保持误差,仿真结果不会太差,但和你论文里写的控制律就对不上了。

4.3 图像置乱和XOR扩散的代码实现

同步完成之后,从状态序列里提取密钥流。先取同步收敛后的稳定段,丢弃前面的瞬态,然后对每个采样点做量化:

state_seq = Y_record(start_idx:end, ref_node_dim); state_seq = abs(state_seq); key_byte = mod(floor(state_seq * 1e12), 256); key_byte = uint8(key_byte(:));

这里取1e12作为放大倍数,目的就是让混沌状态的小数部分充分展开。实际操作时,可以取两个不同节点在不同维度上的状态序列,分别生成key1和key2。key1用于置乱,key2用于扩散。

图像本身的处理流程,我先假设输入是灰度图,如果是彩色图可以拆成R、G、B三个通道分别处理,或者直接转灰度验证链路。为了简化变量类型处理的麻烦,先把明文像素拉成一维列向量:

plain_img = imread('cameraman.tif'); [M, N] = size(plain_img); pixel_len = M * N; plain_vector = double(plain_img(:));

第一步置乱。经典做法是用密钥序列的排序索引把明文像素重新排列:

if length(key1) < pixel_len key1 = repmat(key1, ceil(pixel_len / length(key1)), 1); end key1 = key1(1:pixel_len); [~, sort_idx] = sort(key1); scrambled = plain_vector(sort_idx);

第二步扩散。逐像素XOR并加入前一个密文值,形成链式结构。这样单个像素的改动会传播到后续所有像素,破解难度显著提升。

scrambled = uint8(scrambled); cipher = zeros(pixel_len, 1, 'uint8'); init_value = 137; % 自定义初始扰动 key2 = key2(1:pixel_len); prev = init_value; for i = 1:pixel_len t1 = bitxor(scrambled(i), prev); cipher(i) = bitxor(t1, key2(i)); prev = cipher(i); end cipher_img = reshape(cipher, [M, N]);

解密时顺序完全反过来。先逆扩散,再逆置乱。逆扩散要从密文尾部开始往回推:

recovered_scrambled = zeros(pixel_len, 1, 'uint8'); recovered_scrambled(1) = bitxor(bitxor(cipher(1), key2(1)), init_value); for i = pixel_len:-1:2 recovered_scrambled(i) = bitxor(bitxor(cipher(i), key2(i)), cipher(i - 1)); end

逆置乱时用排序索引的反函数恢复明文顺序:

inverse_idx = zeros(pixel_len, 1); inverse_idx(sort_idx) = (1:pixel_len)'; recovered_vector = recovered_scrambled(inverse_idx); recovered_img = reshape(recovered_vector, [M, N]);

如果所有参数都对齐,recovered_img应该和plain_img完全一致。实际仿真中,我一般用PSNR判断还原质量,正常情况PSNR应该是无穷大或者至少300 dB以上,因为整个过程几乎没有信息损失。如果得到的是几十dB,说明某个环节存在值域截断错误,最常见的根源就是uint8转换和double转换混用。

4.4 安全性指标:相关性、信息熵、NPCR和UACI

写完加解密只是第一步,论文或者项目里通常还要给几组安全指标证明方案有效。这里说四个最常用的指标,顺便给Matlab实现思路。

第一个是相邻像素相关性。取明文和密文图像水平方向相邻像素对,计算相关系数。明文图像相邻像素相关性通常极高,可能到0.9以上;加密后应该趋近于零,理想情况接近0.01以下。垂直方向和对角线方向同理。相关系数用自带corrcoef函数就能算:

vec1 = double(img(:, 1:end-1)); vec2 = double(img(:, 2:end)); r = corrcoef(vec1(:), vec2(:));

第二个是图像信息熵。8位灰度图的最大熵是8比特,熵越接近8说明灰度分布越均匀。明文图像通常只有7左右,如果密文图像能做到7.99以上,说明扩散效果不错:

p = imhist(img) / numel(img); p = p(p > 0); H = -sum(p .* log2(p));

第三个和第四个是NPCR和UACI,用来衡量明文微小变化对密文的影响。做法是对明文图像任意修改一个像素,分别用同一密钥加密得到两幅密文,计算它们之间有多少比例的像素发生了变化,以及平均变化幅度有多大。理论参考值是NPCR大于99.6%,UACI在33.4%左右。如果这两项不达标,通常说明扩散轮数不够,建议把正向XOR扩散改成正向加反向两轮扩散,也就是加密时先从头到尾做一遍,再从尾到头做一遍。

D = double(cipher1 ~= cipher2); NPCR = sum(D(:)) / numel(cipher1) * 100; UACI = sum(abs(double(cipher1(:)) - double(cipher2(:)))) / (255 * numel(cipher1)) * 100;

这几个指标跑完之后,基本就能在论文里比较完整地评价一个图像加密方案了。

5. 同步和加密代码中容易踩的坑

5.1 误差一直不收敛:先查耦合方向和矩阵定义

同步误差不收敛,是最常见的失败模式。排查顺序很重要,不要一上来就调控制器参数。第一步先看耦合矩阵的定义,Matlab矩阵乘法方向不同,网络方程差异很大。常用的复杂网络模型里,拉普拉斯矩阵的行和为零,耦合项写成L乘以状态向量;如果你按邻接矩阵处理又搞错了符号,状态误差会越走越偏。我自己调试时会把“无控制情况下的误差增长率”先单独跑出来,看在没有脉冲作用时,网络靠耦合是否能够维持基本的一致趋势。如果无控情况下误差就在快速增长,那控制器设计得再好也很难救回来,因为两个脉冲之间散得太快。

第二步查参考节点选取。参考节点本身不能同时被控制,它必须保持“自由跑”的状态,才有资格当其他节点的基准。如果你不小心把参考节点也加上了控制信号,整个参考轨道就变了,响应端的同步目标也随之漂移,误差当然收敛不了。

第三步查初值。接收端网络初始状态如果离参考轨道太远,比如初始误差上百,那么单个脉冲的有限幅值可能不足以在预期时间内把误差拉回来。这种情况下需要增加脉冲次数,或者先让网络在较大耦合强度下预同步一段时间,再切换到带控制的精细同步段。

5.2 解密图像出现条纹或者噪点:密钥流没对齐

解密失败的大多数原因不是算法写错,而是密钥流没有严格对齐。加密端可能丢弃了前2秒不稳定阶段作为预热,但解密端忘记丢弃同样的长度;或者加密端从第3个节点取状态,解密端却从第4个节点取。这都导致密钥流对不上。

排查技巧有点土但很管用:跑完同步之后,把加密端和解密端生成的前20个字节打印出来对比。如果前几个字节都一样但某一个字节开始劈叉,那就是量化边界问题;如果第一个字节就不一样,基本就是初始状态或参数没有同步成功。处理方式是统一预热时间、统一取点节点、统一量化公式,不要在两套代码里各写一套。

5.3 直方图不平、像素相关性不够低

密钥流来自混沌状态序列,但原始混沌状态值的分布并不均匀,直接量化成0到255字节流时,会保留非均匀性。如果加密后图像的直方图有明显起伏,很可能是加密流程里“扩散”这一步的扰动不够强。

我的建议是加两步处理。第一,对混沌序列在量化前先做异或或者扰动,打破原始分布。第二,加密时把正向XOR扩散改成两轮,第一轮从前往后,第二轮从后往前。第二轮开始之前,先用第一轮的最后一个密文值作为第二轮的初始扰动值,这样任何微小改动都会在整幅图像上扩散开。实测下来,两轮扩散的NPCR和UACI指标通常能甩开单轮扩散一大截。

5.4 ode45太慢或者数值发散

脉冲控制仿真天然需要小步长,因为每个脉冲区间都要重新积分一次,而且混沌系统对数值误差非常敏感。如果ode45默认的误差容限不合适,可能导致计算结果出现虚假发散。建议设置相对误差容限在1e-6左右,同时把每个脉冲区间内的最小积分步长限制住。

如果仿真总时长很长、节点数很多,ode45会变得很慢。一个可行方案是把整个仿真拆

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 4:28:30

CPU水冷散热器选购与安装避坑指南:满载不降频

最近帮朋友装机&#xff0c;又碰上一次“CPU温度压不住”的现场。主机配置不低&#xff0c;CPU还是带K后缀的中高端型号&#xff0c;结果跑压力测试时风扇直接拉满&#xff0c;温度卡在95℃以上&#xff0c;机箱像个小暖炉。拆开一看&#xff0c;他还在用那颗原装小塔散热器。我…

作者头像 李华
网站建设 2026/9/9 4:27:09

Linux下Tomcat 8.5.35生产环境部署全流程实战

简介&#xff1a;Linux版Tomcat 8.5.35压缩包面向需要在Linux服务器上运行Java Web应用的开发与运维人员&#xff0c;封装了Catalina、Jasper、Coyote等核心组件&#xff0c;可直接解压用于部署Servlet/JSP项目&#xff0c;免去手动编译配置。资源共645个文件&#xff0c;约9.2…

作者头像 李华
网站建设 2026/9/9 4:27:01

AI Bot Scraper实战:突破SSE流与浏览器限制,结构化抓取ChatGPT对话

做数据分析的人大概都动过这个念头&#xff1a;能不能把 ChatGPT 的回答批量抓下来&#xff0c;整理成结构化数据&#xff0c;直接喂给下一步流程&#xff1f;我自己第一次尝试的时候&#xff0c;天真地以为就是个普通爬虫的活儿&#xff0c;结果发现页面上的回答倒是看得见&am…

作者头像 李华
网站建设 2026/9/9 4:25:23

智能AR眼镜怎么选?四款热门型号深度横评与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/9 4:25:10

入门微单vs二十倍专业器材:实拍差距到底有多大

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/9 4:24:23

鲸鱼算法求解线性规划:罚函数设计与Python实现

1. 为什么要用鲸鱼算法去解线性规划 1.1 线性规划不是已经有标准解法了吗 线性规划是我接触运筹学和数学建模时最先遇到的优化模型。标准形式很简单&#xff0c;目标函数和约束条件都是线性的&#xff0c;例如&#xff1a; 最大化 c^T x &#xff0c;满足 A x < b &am…

作者头像 李华