#pragma once
#include "pandaAlgorithm.h"
#include "genome.h"

#include <memory>
#include <string>
#include <vector>
#include <map>
#include <time.h>
#include<stdlib.h>

using namespace std;

#define MAX_RANDOM 2147483647.0

class  OptScheduling;
/**
   遗传算法引擎
*/
class PANDAALGORITHM_API  GenAlg
{
public:
    //构造函数  
   explicit GenAlg(std::shared_ptr<OptScheduling>optScheduling);

    //初始化变量  
    void reset();

    //初始化函数  
    void init(int popsize, double MutRate, double CrossRate, int GenLenght, double LeftPoint, double RightPoint);

    // 计算mTotalFitness, mBestFitness, mWorstFitness, mAverageFitness等变量  
    void calculateBestWorstAvTot();

    // 轮盘赌选择函数  
    Genome chromoRoulette();

    // 基因变异函数（实值编码）  
    void mutate(vector<double>& chromo);

    //这函数产生新一代基因  
    void epoch(vector<Genome>& vecNewPop);

    // 获取最好适应度的基因组
    Genome bestFitness();

    // 获取平均适应度
    double averageFitness();

    /**
    * @brief 解码，将基因型解码成基础算法计算所需数据
    * @param [genVals] 解析的数据集合
    */
    void decoding(vector<map<string, float>> & genVals);
  
    // 选择运算，前群体中适应度较高的个体按某种规则或模型遗传到下一代群体中
    void select(vector<Genome>& genVec);

    /**
     * @brief 交叉重组
     * @param [parent] 父代个体
     * @param [son] 产生子代
     */
    void crossover(const vector<Genome>& parent, vector<Genome>& son );

    /**
    * @brief 根据监测点计算值，计算个体自适应度
    * @param [cost] 能耗
    * @param [monitorValues] 监测点的值
    * @return 适应度值
    */
    double fitnessfunction(float cost, map<string,double>& monitorValues);

    /**
     * @brief 更新种群个体自适应度
     * @param [index] 种群的个体
     * @param [fitNess] 个体适应度
     */
    void updateGenomeFitNess(int index, double fitNess);

    void setPumpVec(const vector<string>& pumpVec) { mPumpVec = pumpVec; }
private:
    // 产生[a,b)之间的浮点数
    double random(int a=0, int b= RAND_MAX);

    // 交叉重组，产生新的个体
    Genome crossover(const Genome& gen1, const Genome& gen2);

private:
    // 当前种群 
    vector <Genome>   vecPop;

    // 下一代种群
    vector<Genome> nextPopulation;

    // 中间代种群
    vector<Genome> midPopulation;

    // 种群数量  
    int mPopSize;

    // 每一条染色体的基因的总数目  
    int mChromoLength;

    // 所有个体对应的适应性评分的总和  
    double mTotalFitness;

    // 在所有个体当中最适应的个体的适应性评分  
    double mBestFitness;

    // 记录最有个体基因值
    Genome mBestGenoMe;

    Genome mWorthGenoMe;

    // 所有个体的适应性评分的平均值  
    double mAverageFitness;

    // 在所有个体当中最不适应的个体的适应性评分  
    double mWorstFitness;

    // 最适应的个体在m_vecPop容器里面的索引号  
    Genome mFittestGenome;

    // 基因突变的概率,一般介于0.05和0.3之间  
    double mMutationRate = 0.2;

    // 基因交叉的概率一般设为0.7  
    double mCrossoverRate = 0.7;

    // 代数的记数器  
    int mGeneration;

    // 最大变异步长  
    double mMaxPerturbation;

    // 左边界
    double mLeftPoint;

    // 右边界
    double mRightPoint;

    // 
    vector<string> mPumpVec;

    // 优化调度函数
    std::shared_ptr<OptScheduling> mOptScheduling = nullptr;
};
