KDB/q基于输出精度的累加实现:爬山算法迭代问询
KDB/q 爬山算法实现方案
先明确你已实现的两个函数(如果你的实现逻辑不同,替换成自己的即可):
// 精度计算函数:返回0-1的匹配度,值越接近1说明列表和与目标越匹配 calculateAccuracy:{[lst; target] 1 - abs[sum lst - target] % target // 基于相对误差的精度计算,可按需调整 } // 单值调整函数:随机修改列表中一个元素的值 changeOneNumber:{[lst] idx: rand count lst; // 示例:随机给选中元素±1,可替换为你的调整逻辑(比如按比例增减) lst[idx] +: (rand 2) * 2 - 1; lst }
主爬山函数实现
下面是包含迭代对比、阈值调整、进度记录的核心函数:
hillClimb:{[initLst; target; maxIters:1000; threshold:0.05] // 初始化当前状态 currentLst: initLst; currentAcc: calculateAccuracy[currentLst; target]; // 初始化进度记录表:存储每轮迭代的关键信息 progress: ([] iter:(); acc:(); sumLst:(); accepted:()); // 执行指定次数迭代 do[maxIters; // 生成新列表并计算其精度 newLst: changeOneNumber[currentLst]; newAcc: calculateAccuracy[newLst; target]; // 判断是否接受新列表:要么精度更高,要么触发5%的随机跳出阈值 accept: newAcc > currentAcc or rand 1.0 < threshold; // 更新当前最优状态 $[accept; currentLst: newLst; currentAcc: newAcc; ; // 不接受则保持原状态 ]; // 追加当前迭代进度到记录表 progress,: (enlist count progress; enlist currentAcc; enlist sum currentLst; enlist accept); ]; // 返回最终结果:最优列表、最终精度、完整迭代进度 (currentLst; currentAcc; progress) }
调用示例
// 测试:初始列表[1,2,3],目标和为10,执行1000次迭代 result: hillClimb[1 2 3; 10; 1000; 0.05]; // 提取结果 finalLst: result[0]; // 最终调整后的列表 finalAcc: result[1]; // 最终匹配精度 progressLog: result[2]; // 所有迭代的进度记录 // 查看前5条进度记录 5#progressLog
关键逻辑说明
- 当前与新列表对比:通过
currentAcc和newAcc的数值大小直接判断精度优劣,优先保留精度更高的列表。 - 5%阈值规避局部最优:每次迭代生成0-1的随机数,若小于0.05则强制接受新列表,哪怕精度更低,以此跳出局部最优解的陷阱。
- 迭代进度记录:用KDB/q的表结构
progress存储每轮的迭代次数、当前精度、列表和、是否接受新值,通过,:操作符实现记录的累加。
内容的提问来源于stack exchange,提问作者mmv456
相关产品推荐
相关产品推荐

