You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
267 lines
9.3 KiB
C
267 lines
9.3 KiB
C
|
3 weeks ago
|
#ifndef NMCALCULATIONAUTOFITGA_H
|
||
|
|
#define NMCALCULATIONAUTOFITGA_H
|
||
|
|
|
||
|
|
#include <QObject>
|
||
|
|
#include <QVector>
|
||
|
|
#include <QPointF>
|
||
|
|
#include <QString>
|
||
|
|
#include <QTimer>
|
||
|
|
#include <QApplication>
|
||
|
|
#include <QDateTime>
|
||
|
|
#include <QCoreApplication>
|
||
|
|
#include <QDir>
|
||
|
|
#include <QDebug>
|
||
|
|
#include <QTime>
|
||
|
|
|
||
|
|
#include "nmCalculation_global.h"
|
||
|
|
|
||
|
|
class nmDataWellBase;
|
||
|
|
|
||
|
|
enum StopReasonGA {
|
||
|
|
GA_CONTINUE_OPTIMIZATION = 0,
|
||
|
|
GA_TARGET_ACHIEVED,
|
||
|
|
GA_TRUE_CONVERGENCE,
|
||
|
|
GA_LOCAL_OPTIMUM,
|
||
|
|
GA_MAX_ITERATIONS,
|
||
|
|
GA_USER_STOPPED,
|
||
|
|
GA_CONSECUTIVE_FAILURES,
|
||
|
|
GA_OPTIMIZATION_FAILED
|
||
|
|
};
|
||
|
|
|
||
|
|
struct GAIndividual
|
||
|
|
{
|
||
|
|
QVector<double> genes; // 基因(参数值)
|
||
|
|
double fitness; // 适应度值
|
||
|
|
bool isEvaluated; // 是否已评估
|
||
|
|
|
||
|
|
GAIndividual() : fitness(1e10), isEvaluated(false) {}
|
||
|
|
};
|
||
|
|
|
||
|
|
class NMCALCULATION_EXPORT nmCalculationAutoFitGA : public QObject
|
||
|
|
{
|
||
|
|
Q_OBJECT
|
||
|
|
|
||
|
|
public:
|
||
|
|
explicit nmCalculationAutoFitGA(QObject* parent = nullptr);
|
||
|
|
virtual ~nmCalculationAutoFitGA();
|
||
|
|
|
||
|
|
// ==================== 公共接口方法 ====================
|
||
|
|
void setTargetLogLogData(const QVector<QVector<double>>& targetData);
|
||
|
|
bool startAutoFitting();
|
||
|
|
void stopFitting();
|
||
|
|
bool isRunning() const;
|
||
|
|
int getCurrentGeneration() const;
|
||
|
|
QVector<double> getBestSolution() const;
|
||
|
|
double getBestFitness() const;
|
||
|
|
QString getLastError() const;
|
||
|
|
void resetOptimizer();
|
||
|
|
|
||
|
|
void setGATargetWellName(const QString& wellName);
|
||
|
|
|
||
|
|
signals:
|
||
|
|
void progressUpdated(int generation, double bestFitness);
|
||
|
|
void fittingFinished(bool success, const QString& message);
|
||
|
|
void logMessageGenerated(const QString& message);
|
||
|
|
|
||
|
|
private slots:
|
||
|
|
void updateProgress();
|
||
|
|
|
||
|
|
private:
|
||
|
|
|
||
|
|
// 临时目录管理
|
||
|
|
void initializeTemporaryDirectory();
|
||
|
|
void cleanupTemporaryDirectory();
|
||
|
|
bool removeDirectoryRecursively(const QString& path);
|
||
|
|
|
||
|
|
// ==================== 数据加载方法 ====================
|
||
|
|
// 从数据管理器加载所有配置
|
||
|
|
bool loadAllConfigFromDataManager();
|
||
|
|
// 加载优化配置
|
||
|
|
void loadOptimizationConfig();
|
||
|
|
// 加载参数边界
|
||
|
|
void loadParameterBounds();
|
||
|
|
// 提取用户初始值
|
||
|
|
void extractUserInitialValues();
|
||
|
|
// ==================== 遗传算法核心方法 ====================
|
||
|
|
// 初始化种群
|
||
|
|
void initializePopulation();
|
||
|
|
// 评估基因
|
||
|
|
double evaluateGenes(const QVector<double>& genes);
|
||
|
|
// 评估个体
|
||
|
|
double evaluateIndividual(GAIndividual& individual);
|
||
|
|
// 评估种群
|
||
|
|
void evaluatePopulation();
|
||
|
|
// 选择操作
|
||
|
|
int tournamentSelection();
|
||
|
|
int rouletteWheelSelection();
|
||
|
|
|
||
|
|
// 交叉操作
|
||
|
|
void crossover(const GAIndividual& parent1, const GAIndividual& parent2,
|
||
|
|
GAIndividual& offspring1, GAIndividual& offspring2);
|
||
|
|
void singlePointCrossover(const GAIndividual& parent1, const GAIndividual& parent2,
|
||
|
|
GAIndividual& offspring1, GAIndividual& offspring2);
|
||
|
|
void uniformCrossover(const GAIndividual& parent1, const GAIndividual& parent2,
|
||
|
|
GAIndividual& offspring1, GAIndividual& offspring2);
|
||
|
|
|
||
|
|
// 变异操作
|
||
|
|
void mutate(GAIndividual& individual);
|
||
|
|
void gaussianMutation(GAIndividual& individual);
|
||
|
|
void polynomialMutation(GAIndividual& individual);
|
||
|
|
|
||
|
|
// 精英保留
|
||
|
|
void applyElitism(QVector<GAIndividual>& newPopulation);
|
||
|
|
// 更新种群统计
|
||
|
|
void updatePopulationStatistics();
|
||
|
|
// 收敛检查
|
||
|
|
bool checkConvergence();
|
||
|
|
// 自适应参数更新
|
||
|
|
void adaptiveParameterUpdate(int generation);
|
||
|
|
|
||
|
|
// ==================== 智能收敛判断方法 ====================
|
||
|
|
// 分析优化状态
|
||
|
|
StopReasonGA analyzeOptimizationStatus();
|
||
|
|
// 检查真收敛
|
||
|
|
bool checkTrueConvergence() const;
|
||
|
|
// 检查局部最优陷阱
|
||
|
|
bool checkLocalOptimumTrap() const;
|
||
|
|
// 计算种群多样性
|
||
|
|
double calculatePopulationDiversity() const;
|
||
|
|
// 计算适应度方差
|
||
|
|
double calculateFitnessVariance(int windowSize) const;
|
||
|
|
// 计算长期改进
|
||
|
|
double calculateLongTermImprovement(int windowSize) const;
|
||
|
|
// 更新收敛指标
|
||
|
|
void updateConvergenceMetrics();
|
||
|
|
// 最终结果验证和保护
|
||
|
|
void validateAndProtectFinalResult();
|
||
|
|
|
||
|
|
// ==================== 参数处理方法 ====================
|
||
|
|
// 参数验证
|
||
|
|
bool validateParameters(const QVector<double>& parameters) const;
|
||
|
|
// 双对数数据验证
|
||
|
|
bool validateLogLogData(const QVector<QVector<double>>& logLogData) const;
|
||
|
|
// 初始值验证
|
||
|
|
bool validateInitialValues() const;
|
||
|
|
// 应用参数到数据管理器
|
||
|
|
void applyParametersToDataManager(const QVector<double>& parameters);
|
||
|
|
// 更新储层参数
|
||
|
|
void updateReservoirParameters(const QVector<double>& parameters);
|
||
|
|
// 更新井参数
|
||
|
|
void updateWellParameters(const QVector<double>& parameters);
|
||
|
|
// 更新井到数据管理器
|
||
|
|
void updateWellToDataManager(nmDataWellBase* pWell);
|
||
|
|
// 参数边界约束
|
||
|
|
void clampToLimits(QVector<double>& parameters) const;
|
||
|
|
|
||
|
|
// ==================== 求解器相关方法 ====================
|
||
|
|
// 运行求解器
|
||
|
|
QVector<QVector<double>> runSolver();
|
||
|
|
// 运行EXE求解器
|
||
|
|
QVector<QVector<double>> runSolverExe();
|
||
|
|
// 运行Dll求解器
|
||
|
|
QVector<QVector<double>> runSolverDll();
|
||
|
|
// 验证求解器结果
|
||
|
|
bool validateSolverResult(const QVector<QVector<double>>& result) const;
|
||
|
|
|
||
|
|
// ==================== 数据处理方法 ====================
|
||
|
|
// 插值数据
|
||
|
|
QVector<QPointF> interpolateData(const QVector<QPointF>& source,
|
||
|
|
const QVector<double>& targetX) const;
|
||
|
|
// 计算双对数曲线误差
|
||
|
|
double calculateLogLogCurveError(const QVector<QVector<double>>& target,
|
||
|
|
const QVector<QVector<double>>& result) const;
|
||
|
|
// 计算曲线误差
|
||
|
|
double calculateCurveError(const QVector<QPointF>& curve1,
|
||
|
|
const QVector<QPointF>& curve2) const;
|
||
|
|
|
||
|
|
// ==================== 工具方法 ====================
|
||
|
|
// 生成0-1随机数
|
||
|
|
double random01() const;
|
||
|
|
// 高斯随机数
|
||
|
|
double gaussianRandom(double mean, double stddev) const;
|
||
|
|
// 获取启用参数数量
|
||
|
|
int getEnabledParameterCount() const;
|
||
|
|
// 保存优化结果
|
||
|
|
void saveOptimizationResult();
|
||
|
|
|
||
|
|
|
||
|
|
private:
|
||
|
|
// ==================== 常量定义 ====================
|
||
|
|
static const double MIN_FITNESS_IMPROVEMENT;
|
||
|
|
static const double MUTATION_STRENGTH;
|
||
|
|
static const int CONVERGENCE_CHECK_INTERVAL;
|
||
|
|
static const int MAX_STAGNATION_GENERATIONS;
|
||
|
|
|
||
|
|
// ==================== 核心状态变量 ====================
|
||
|
|
bool m_isRunning; // 是否正在运行
|
||
|
|
bool m_shouldStop; // 是否应该停止
|
||
|
|
bool m_isPaused; // 是否暂停
|
||
|
|
int m_currentGeneration; // 当前代数
|
||
|
|
|
||
|
|
// 适应度统计
|
||
|
|
double m_bestFitness; // 最优适应度
|
||
|
|
double m_worstFitness; // 最差适应度
|
||
|
|
double m_averageFitness; // 平均适应度
|
||
|
|
double m_previousBestFitness; // 上一代最优适应度
|
||
|
|
|
||
|
|
// ==================== GA算法参数 ====================
|
||
|
|
int m_populationSize; // 种群大小
|
||
|
|
int m_maxGenerations; // 最大代数
|
||
|
|
double m_targetError; // 目标误差
|
||
|
|
double m_crossoverRate; // 交叉概率
|
||
|
|
double m_mutationRate; // 变异概率
|
||
|
|
double m_elitismRate; // 精英保留比例
|
||
|
|
int m_tournamentSize; // 锦标赛选择大小
|
||
|
|
bool m_useUniformCrossover; // 是否使用均匀交叉
|
||
|
|
|
||
|
|
// ==================== 种群和个体 ====================
|
||
|
|
QVector<GAIndividual> m_population; // 当前种群
|
||
|
|
QVector<GAIndividual> m_eliteIndividuals; // 精英个体
|
||
|
|
GAIndividual m_bestIndividual; // 全局最优个体
|
||
|
|
|
||
|
|
// ==================== 评估统计 ====================
|
||
|
|
int m_totalEvaluations; // 总评估次数
|
||
|
|
int m_successfulEvaluations; // 成功评估次数
|
||
|
|
int m_evaluationInProgress; // 正在进行的评估计数
|
||
|
|
int m_consecutiveFailures; // 连续失败次数
|
||
|
|
|
||
|
|
// ==================== 精英保护相关 ====================
|
||
|
|
QVector<double> m_initialValues; // 用户初始参数值
|
||
|
|
QVector<double> m_userInitialSolution; // 用户初始解
|
||
|
|
double m_userInitialFitness; // 用户初始适应度
|
||
|
|
int m_consecutiveFailedGenerations; // 连续失败代数
|
||
|
|
int m_maxConsecutiveFailures; // 最大允许连续失败数
|
||
|
|
bool m_hasValidUserSolution; // 是否有有效的用户解
|
||
|
|
double m_improvementThreshold; // 改进阈值
|
||
|
|
|
||
|
|
// ==================== 收敛判断相关 ====================
|
||
|
|
double m_diversityThreshold; // 多样性阈值
|
||
|
|
double m_convergenceVarianceThreshold; // 收敛方差阈值
|
||
|
|
int m_trueConvergenceWindow; // 真收敛判断窗口
|
||
|
|
int m_localOptimumWindow; // 局部最优判断窗口
|
||
|
|
double m_nearTargetFactor; // 接近目标的因子
|
||
|
|
double m_farTargetFactor; // 远离目标的因子
|
||
|
|
|
||
|
|
// ==================== 历史记录 ====================
|
||
|
|
QVector<double> m_convergenceHistory; // 收敛历史
|
||
|
|
QVector<double> m_diversityHistory; // 多样性历史
|
||
|
|
|
||
|
|
// ==================== 参数配置 ====================
|
||
|
|
QVector<bool> m_parameterSelected; // 参数选择状态
|
||
|
|
QVector<double> m_parameterLower; // 参数下界
|
||
|
|
QVector<double> m_parameterUpper; // 参数上界
|
||
|
|
QVector<int> m_enabledParamIndices; // 启用参数索引
|
||
|
|
|
||
|
|
// ==================== 目标数据 ====================
|
||
|
|
QVector<QVector<double>> m_targetLogLogData; // 目标双对数数据
|
||
|
|
|
||
|
|
// ==================== 其他 ====================
|
||
|
|
QString m_lastError; // 最后错误信息
|
||
|
|
QTimer* m_progressTimer; // 进度更新定时器
|
||
|
|
// DLL求解器需要的临时目录
|
||
|
|
QString m_tempDirectory;
|
||
|
|
|
||
|
|
QString m_targetWellName;// 目标井名称
|
||
|
|
};
|
||
|
|
|
||
|
|
#endif // NMCALCULATIONAUTOFITGA_H
|