KCC v2.0 测地线估计器-SIM 2(geodesic_sim.js: 500 step drain)
📅 2026/7/11 15:32:45
👁️ 阅读次数
📝 编程学习
// geodesic_sim.js// KCC v2.0 测地线估计器// 参数完全由物理/数学约束导出:p=12%, γ=1.1, C=3// 定点数运算,线性同余随机数,无探测逻辑错误// 测试:全频谱路径检测、动态队列拥塞安全、死锁恢复// ====================== 定点数常量 ======================constSCALE=1024;// 2^10,用于固定点乘法/移位的基数constSHIFT=10;// 右移位数// ====================== 估计器核心 ======================classGeodesicEstimator{/** * @param {number} T - 真实传播延迟 (微秒) * @param {number} sigma - 噪声标准差 (微秒) */constructor(T,sigma){this.x=T*SCALE;// x_est 的定点表示 (内部单位 = 微秒 × SCALE)this.mr=T;// min_rtt (微秒, 原始精度)this.conf=0;// 确认计数器 (累积)this.T=T;// 当前路径的 T_prop (微秒)this.probe=0;// 探测周期计数器this.sigma=sigma;}// Box‑Muller 高斯噪声生成 (需要外部提供均匀随机函数 rng)staticgauss(rng,mean=0,std=1){constu1=rng();constu2=rng();returnmean+std*Math.sqrt(-2*Math.log(u1))*Math.cos(2*Math.PI*u2);}/** * 单步迭代 * @param {function} rng - 返回 [0,1) 均匀分布随机数的函数 * @param {number} rtt - 当前传入的 RTT 观测值 (微秒) * @param {number} ql - 队列延迟 (微秒),0 表示队列为空 */step(rng,rtt,ql=0){this.probe++;letactualRTT=rtt;// 实际使用的观测值// ------ 探测逻辑 (每2000步尝试一次) ------if(this.probe>=2000){this.probe=0;// 仅在队列完全空闲时才允许使用纯净观测(模拟发送探测包)if(ql===0){// 用 T_prop + 噪声 代替真实 RTT,等效于主动探测actualRTT=this.T+Math.round(GeodesicEstimator.gauss(rng,0,this.sigma));}// 若 ql != 0,放弃本次探测,actualRTT 保持原始 rtt// 探测状态随即结束,不会污染后续步骤}// ------ min_rtt 的原始精度更新 ------if(actualRTT<this.mr)this.mr=actualRTT;// ------ 测地线更新 ------constz=actualRTT*SCALE;// 定点观测constv=z-this.x;if(v<=0){// G1: 向下分支 (观测 ≤ 当前估计)this.x=Math.min(this.x,z);}else{// G2: 向上分支 (观测 > 当前估计)constgrowth=Math.floor((this.x*12)/100);// 12% 几何增长this.x=Math.min(this.x+growth,z);// 上限压制于观测值// G3: 路径增长检测器constthreshold=Math.floor((this.mr*11*SCALE)/10);// 1.1 * min_rtt (定点)if(this.x>threshold){this.conf++;// 累积确认}elseif(this.x<this.mr*SCALE){this.conf=0;// 物理底线重置}if(this.conf>=3){// 确认路径增长,更新 min_rttthis.mr=Math.floor(this.x/SCALE);this.conf=0;}}}/** * 返回用于 BDP 计算的 RTT 安全值 (微秒) * 始终 ≤ 真实传播延迟 */bdp(){constxUs=Math.floor(this.x/SCALE);returnxUs<this.mr?xUs:this.mr;// 等价于 min(x_est, min_rtt)}}// ====================== 伪随机数生成器 (可复现) ======================functionseedRandom(seed){returnfunction(){seed=(seed*1664525+1013904223)&0xffffffff;return(seed>>>0)/0xffffffff;};}// ====================== 测试配置 ======================constRTTs=[100,200,300,500,750,1000,1400,2000,3000,5000,10000,20000,50000,100000,200000,300000,500000,750000,1000000];constSTEPS=[5,10,25,50,100,200];// 路径增幅百分比constNS=20;// 每个测试的随机种子数// ====================== 测试 1:全频谱路径增长检测 ======================functiontestFullSpectrum(){console.log('===========================================================');console.log(`GEODESIC FULL-SPECTRUM VERIFICATION (${NS}seeds per case)`);console.log('===========================================================');letfailures=0;for(constTofRTTs){constsigma=Math.max(1,Math.floor(T/100));for(constspofSTEPS){constTnew=T+Math.floor(T*sp/100);if(Tnew===T)continue;letmiss=0;constdelays=[];for(letseed=0;seed<NS;seed++){constrng=seedRandom(T*1000+sp+seed);constest=newGeodesicEstimator(T,sigma);// 预热 2000 步 (路径未变化)for(leti=0;i<2000;i++){constrtt=Math.max(1,T+Math.round(GeodesicEstimator.gauss(rng,0,sigma)));est.step(rng,rtt,0);}// 路径变化后测试 500 步letdetected=false;for(lets=1;s<=500;s++){constrtt=Math.max(1,Tnew+Math.round(GeodesicEstimator.gauss(rng,0,sigma)));est.step(rng,rtt,0);if(est.bdp()>T+Math.floor(T*0.02)){// 超过原 T 的 2% 视为检测成功delays.push(s);detected=true;break;}}if(!detected)miss++;}if(miss>NS/2){console.log(`FAIL: T=${T.toString().padStart(7)}us +${sp.toString().padStart(3)}%:${miss}/${NS}`);failures++;}}if(failures===0)console.log(`T=${T.toString().padStart(7)}us: ok`);}returnfailures;}// ====================== 测试 2:动态队列拥塞安全 ======================functiontestCongested(){console.log('\n--- CONGESTED (dynamic queue, realistic TCP) ---');constscenarios=[{T:1400,sigma:20,q_max:400,label:'DC'},{T:50000,sigma:200,q_max:5000,label:'WAN'},{T:300000,sigma:500,q_max:20000,label:'LH'}];conststeps=50000;// 仿真步数constdrainInterval=500;// 队列排空间隔 (模拟窗口减少)for(const{T,sigma,q_max,label}ofscenarios){letok=0;for(letseed=0;seed<20;seed++){constrng=seedRandom(T+seed);constest=newGeodesicEstimator(T,sigma);letqueue=0;for(leti=0;i<steps;i++){constnoise=Math.round(GeodesicEstimator.gauss(rng,0,sigma));// 队列动态:周期性排空,其余时间缓慢变化if(i%drainInterval===0){queue=0;// 窗口减少,队列瞬间排空}else{queue+=Math.round(GeodesicEstimator.gauss(rng,0,sigma*0.5));queue=Math.max(0,Math.min(q_max,queue));}constrtt=Math.max(1,T+queue+noise);est.step(rng,rtt,queue);// 传递真实队列值给探测逻辑}if(est.bdp()<T+Math.floor(T*0.02))ok++;}console.log(`${label}:${ok}/20 safe`+(ok<16?' <-- WARNING':''));}}// ====================== 测试 3:死锁恢复 ======================functiontestDeadlock(){console.log('\n--- DEADLOCK RECOVERY ---');for(const[T,sigma]of[[1400,20],[50000,200]]){letok=0;for(letseed=0;seed<100;seed++){constrng=seedRandom(T+seed*9999);constest=newGeodesicEstimator(T,sigma);est.x=Math.floor(T*5.5)*SCALE;// 模拟膨胀至 5.5 倍for(leti=0;i<5000;i++){constrtt=Math.max(1,T+Math.round(GeodesicEstimator.gauss(rng,0,sigma)));est.step(rng,rtt,0);}if(est.bdp()<T*1.1)ok++;}console.log(`T=${T}us:${ok}/100 recovered`+(ok<80?' <-- FAIL':''));}}// ====================== 主程序 ======================conststartTime=Date.now();constfailed=testFullSpectrum();testCongested();testDeadlock();constelapsed=((Date.now()-startTime)/1000).toFixed(1);console.log('\n===========================================================');if(failed===0){console.log(`ALL TESTS PASSED (${elapsed}s)`);}else{console.log(`${failed}FAILURE(S) DETECTED`);}
编程学习
技术分享
实战经验