调整误差计算方式

feature/Model-20260625
lvjunjie 2 weeks ago
parent 00d5cfdca1
commit fdf4a10f4c

@ -261,7 +261,7 @@ private:
double calculateCurveError(const QVector<QPointF>& curve1, const QVector<QPointF>& curve2) const; double calculateCurveError(const QVector<QPointF>& curve1, const QVector<QPointF>& curve2) const;
double calculateLogLogCurveError(const QVector<QVector<double> >& target, double calculateLogLogCurveError(const QVector<QVector<double> >& target,
const QVector<QVector<double> >& result) const; const QVector<QVector<double> >& result) const;
double calculateWeightedPointError(double target, double result, double timeWeight) const; double calculatePointError(double target, double result) const;
private: private:
// ===== 运行状态 ===== // ===== 运行状态 =====

@ -4529,7 +4529,7 @@ double nmCalculationAutoFitPSO::calculateCurveError(
const QVector<QPointF>& curve1, const QVector<QPointF>& curve2) const const QVector<QPointF>& curve1, const QVector<QPointF>& curve2) const
{ {
// 两条已经对齐到同一 X 网格的曲线误差。 // 两条已经对齐到同一 X 网格的曲线误差。
// 使用“相对误差为主、绝对误差为辅”的点误差,并对极端值做保护 // 点误差保持无量纲,避免油水压力和气井拟压力因数值尺度不同而不可比
if(curve1.size() != curve2.size() || curve1.isEmpty()) { if(curve1.size() != curve2.size() || curve1.isEmpty()) {
return 1e10; return 1e10;
} }
@ -4550,7 +4550,6 @@ double nmCalculationAutoFitPSO::calculateCurveError(
} }
double totalError = 0.0; double totalError = 0.0;
double totalWeight = 0.0;
int validPoints = 0; int validPoints = 0;
for(int i = 0; i < curve1.size(); ++i) { for(int i = 0; i < curve1.size(); ++i) {
@ -4562,33 +4561,16 @@ double nmCalculationAutoFitPSO::calculateCurveError(
continue; continue;
} }
// 自适应权重Y 值越大权重越小,避免大幅值段完全主导误差。 double pointError = calculatePointError(y1, y2);
double weightFactor = qMin(100.0, qAbs(y1) * 0.01);
double weight = 1.0 / (1.0 + weightFactor);
// 相对误差和绝对误差的组合 - 添加数值保护
double yMax = qMax(qAbs(y1), qAbs(y2));
yMax = qMax(1e-12, yMax); // 防止除零
double relativeError = qAbs(y1 - y2) / yMax;
double absoluteError = qAbs(y1 - y2);
// 限制误差值避免爆炸
relativeError = qMin(1e6, relativeError);
absoluteError = qMin(1e6, absoluteError);
// 误差组合:相对误差为主,绝对误差为辅
double pointError = 0.7 * relativeError + 0.3 * absoluteError;
if(isFiniteNumber(pointError) && pointError < 1e10) { if(isFiniteNumber(pointError) && pointError < 1e10) {
totalError += weight * pointError * pointError; totalError += pointError * pointError;
totalWeight += weight;
validPoints++; validPoints++;
} }
} }
if(totalWeight > 0 && validPoints > 0) { if(validPoints > 0) {
double result = sqrt(totalError / totalWeight); double result = sqrt(totalError / validPoints);
// 最终检查 // 最终检查
if(!isFiniteNumber(result)) { if(!isFiniteNumber(result)) {
@ -4775,8 +4757,7 @@ double nmCalculationAutoFitPSO::calculateLogLogCurveError(
} }
} }
double nmCalculationAutoFitPSO::calculateWeightedPointError( double nmCalculationAutoFitPSO::calculatePointError(double target, double result) const
double target, double result, double timeWeight) const
{ {
if(!isFiniteNumber(target) || !isFiniteNumber(result)) { if(!isFiniteNumber(target) || !isFiniteNumber(result)) {
return 1e10; return 1e10;
@ -4792,7 +4773,6 @@ double nmCalculationAutoFitPSO::calculateWeightedPointError(
double relativeError = qAbs(target - result) / qMax(1e-10, yMax); double relativeError = qAbs(target - result) / qMax(1e-10, yMax);
// 组合误差:对数误差占 70%,线性误差占 30%。 // 组合误差:对数误差占 70%,线性误差占 30%。
// timeWeight 当前没有参与最终公式,保留参数是为了后续按时间段加权扩展。
return 0.7 * logError + 0.3 * relativeError; return 0.7 * logError + 0.3 * relativeError;
} }
@ -4867,6 +4847,17 @@ QVector<QVector<double>> nmCalculationAutoFitPSO::runSolverDll()
return result; return result;
} }
// 线程结束后检查真实执行结果,防止失败时复用上一粒子的旧曲线。
dllTask->wait();
if(!dllTask->wasSuccessful()) {
DEBUG_OUT("DLL solver task reported failure");
delete dllTask;
dllTask = nullptr;
--m_evaluationInProgress;
m_consecutiveFailures++;
return result;
}
// 验证结果数据是否已更新。DLL 任务会把结果写回 DataManager 中的目标井对象。 // 验证结果数据是否已更新。DLL 任务会把结果写回 DataManager 中的目标井对象。
nmDataAnalyzeManager* dataManager = nmDataAnalyzeManager::getCurrentInstance(); nmDataAnalyzeManager* dataManager = nmDataAnalyzeManager::getCurrentInstance();
//QVector<nmDataWellBase*> wells = dataManager->getWellDataList(); //QVector<nmDataWellBase*> wells = dataManager->getWellDataList();

Loading…
Cancel
Save