GenAlg.cpp 7.31 KB
Newer Older
1 2 3 4
#include "GenAlg.h"
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
刘乐's avatar
刘乐 committed
5 6
#include <random>
#include "OptScheduling.h"
刘乐's avatar
刘乐 committed
7
#include "FirstOptScheduling.h"
8

刘乐's avatar
刘乐 committed
9
GenAlg::GenAlg(GenType genType):mGenType(genType)
10
{
刘乐's avatar
刘乐 committed
11
    mOptScheduling = std::make_unique<FirstOptScheduling>();
12 13
}

刘乐's avatar
刘乐 committed
14
double GenAlg::random(int min , int max)
15
{
刘乐's avatar
刘乐 committed
16 17 18 19 20
    double m1 = (double)(rand() % 101) / 101;                        // 计算 0,1之间的随机小数,得到的值域近似为(0,1)
    min++;                                                                             //将 区间变为(min+1,max),
    double m2 = (double)((rand() % (max - min + 1)) + min);    //计算 min+1,max 之间的随机整数,得到的值域为[min+1,max]
    m2 = m2 - 1;                                                                        //令值域为[min,max-1]
    return m1 + m2;                                                                //返回值域为(min,max),为所求随机浮点
21 22
}

刘乐's avatar
刘乐 committed
23
void GenAlg::init(int popsize, double MutRate, double CrossRate, int GenLength, double LeftPoint, double RightPoint)
24 25 26 27
{
    mPopSize = popsize;
    mMutationRate = MutRate;
    mCrossoverRate = CrossRate;
刘乐's avatar
刘乐 committed
28
    mChromoLength = GenLength;
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
    mTotalFitness = 0;
    mGeneration = 0;

    mBestFitness = 0.0;
    mWorstFitness = 99999999;
    mAverageFitness = 0;
    mMaxPerturbation = 0.001;

    mLeftPoint = LeftPoint;
    mRightPoint = RightPoint;

    // 清空种群容器,以初始化  
    vecPop.clear();
    for (int i = 0; i < mPopSize; i++)
    {
        // 类的构造函数已经把适应性评分初始化为0  
        vecPop.push_back(Genome());

        // 把所有的基因编码初始化为函数区间内的随机数。  
        for (int j = 0; j < mChromoLength; j++)
        {
刘乐's avatar
刘乐 committed
50 51 52 53 54 55 56 57 58 59 60 61
            switch (mGenType)
            {
            case RealValueCoding:
                vecPop[i].vecGenome.push_back(random(0,MAX_RANDOM) * (mRightPoint - mLeftPoint) + mLeftPoint);
                break;
            case BinaryCoding:
                vecPop[i].mBinaryGenVec.push_back((int)random() % 2);
                break;
            default:
                break;
            }
            
62 63 64 65 66 67 68 69 70 71
        }
    }
}

void GenAlg::mutate(vector<double>& chromo)
{
    // 遵循预定的突变概率,对基因进行突变  
    for (int i = 0; i < chromo.size(); ++i)
    {
       // 如果发生突变的话  
刘乐's avatar
刘乐 committed
72
        if (random(0,1) < mMutationRate)
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
        {
            // 使该权值增加或者减少一个很小的随机数值  
            chromo[i] += ((random() - 0.5) * mMaxPerturbation);

            // 左右边界  
            if (chromo[i] < mLeftPoint)
            {
                chromo[i] = mRightPoint;
            }
            else if (chromo[i] > mRightPoint)
            {
                chromo[i] = mLeftPoint;
            }
        }
    }
}

刘乐's avatar
刘乐 committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
void GenAlg::mutate(vector<char>& chromo)
{
    // 遵循预定的突变概率,对基因进行突变  
    for (int i = 0; i < chromo.size(); ++i)
    {
        // 如果发生突变的话  
        if (random(0,1) < mMutationRate)
        {
            chromo[i] =( chromo[i]&0x01) ^ 0x01;
        }
    }
}

void GenAlg::select()
{

}

void GenAlg::corssver()
{
    // 染色体个数
    int popSize = vecPop.size();

    // 种群数组的索引
    std::vector<int> randIndexVec;
    for (int i = 0; i < popSize; i++)
        randIndexVec.push_back(i);

    // 随机排序,为了随机配对染色体
    std::random_shuffle(randIndexVec.begin(), randIndexVec.end());

    int left = 0;
    int right = popSize-1;
    while (left < right)
    {
        int indexLeft = randIndexVec[left];
        int indexRight = randIndexVec[right];

        // 两个染色体互换
        crossover(vecPop[indexLeft].mBinaryGenVec, vecPop[indexRight].mBinaryGenVec);

        left++;
        right--;
    }
}

void GenAlg::crossover(vector<char>& chromo1, vector<char>& chromo2)
{
    if (chromo1.size() != chromo2.size())
        return;

    int total = chromo1.size();
刘乐's avatar
刘乐 committed
142
   
刘乐's avatar
刘乐 committed
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
    // 基因交叉重组
    for (int i = 0; i < total; i++)
    {
        // 满足交叉概率
        if (random(0, 1) < mCrossoverRate)
        {
            int index = random(0, total);
            for (int i = index; i < total; i++)
            {
                swap(chromo1[i], chromo2[i]);
            }          
        }    
    }
}

158 159 160
Genome GenAlg::chromoRoulette()
{
    // 产生一个 0 到种群总适应性评分总和之间的随机数.  mTotalFitness记录了整个种群的适应性分数总和
刘乐's avatar
刘乐 committed
161
    double slice = (random(0,1)) * mTotalFitness;
162 163 164 165 166 167 168 169 170 171 172 173 174

    // 这个基因将承载转盘所选出来的那个个体.  
    Genome theChosenOne;

    // 累计适应性分数的和.  
    double fitnessSoFar = 0;

    // 遍历总种群里面的每一条染色体。  
    for (int i = 0; i < mPopSize; ++i)
    {
        //累计适应性分数.  
        fitnessSoFar += vecPop[i].fitness;

刘乐's avatar
刘乐 committed
175
        // 如果累计分数大于随机数,就选择此时的基因.  
176 177 178 179 180 181 182 183 184 185 186 187
        if (fitnessSoFar >= slice)
        {
            theChosenOne = vecPop[i];
            break;
        }
    }
    //返回转盘选出来的个体基因  
    return theChosenOne;
}

void GenAlg::calculateBestWorstAvTot()
{
刘乐's avatar
刘乐 committed
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
    int total = vecPop.size();
    for (int i = 0; i < total; i++)
    {
        double fitNessTemp = vecPop[i].fitness;

        // 计算总适应度值
        mTotalFitness += fitNessTemp;

        // 查找最好适应度值
        if (mBestFitness < fitNessTemp)
            mBestFitness = fitNessTemp;

        // 查找最差适应度值
        if (mWorstFitness > fitNessTemp)
            mWorstFitness = fitNessTemp;
    }
204

刘乐's avatar
刘乐 committed
205 206
    // 计算平均适应度
    mAverageFitness = mTotalFitness / (double)total;
207 208 209 210
}

void GenAlg::reset()
{
刘乐's avatar
刘乐 committed
211 212 213 214 215 216 217 218 219 220 221 222 223 224
    mPopSize = 0;
    mMutationRate = 0;
    mCrossoverRate =0;
    mChromoLength = 0;
    mTotalFitness = 0;
    mGeneration = 0;

    mBestFitness = 0.0;
    mWorstFitness = 99999999;
    mAverageFitness = 0;
    mMaxPerturbation = 0.001;

    mLeftPoint =0;
    mRightPoint = 0;
225

刘乐's avatar
刘乐 committed
226 227
    // 清空种群容器,以初始化  
    vecPop.clear();
228 229 230 231 232 233 234 235 236
}

void GenAlg::epoch(vector<Genome>& vecNewPop)
{

}

Genome GenAlg::bestFitness()
{
刘乐's avatar
刘乐 committed
237 238 239
    int maxIndex = -1;
    for (int i = 0; i < vecPop.size(); i++)
    {
刘乐's avatar
刘乐 committed
240
        if (mBestFitness == vecPop[i].fitness)  
刘乐's avatar
刘乐 committed
241 242 243 244 245 246 247 248
            maxIndex = i;    
    }

    // 没找到构造一个空的基因型对象
    if (maxIndex == -1)
        return Genome();

    return vecPop[maxIndex];
249 250 251 252
}

double GenAlg::averageFitness()
{
刘乐's avatar
刘乐 committed
253 254 255
    return mAverageFitness;
}

刘乐's avatar
刘乐 committed
256
double  GenAlg::fitnessfunction(float cost, map<string, double>& monitorValues)
刘乐's avatar
刘乐 committed
257
{
刘乐's avatar
刘乐 committed
258
    // 计算适应
刘乐's avatar
刘乐 committed
259 260
    double objVal = mOptScheduling->objectiveFunction(cost, monitorValues);
    return objVal;
刘乐's avatar
刘乐 committed
261 262
}

刘乐's avatar
刘乐 committed
263
void GenAlg::encoding(map<string, int>& phenotype, vector<char>& chromo)
刘乐's avatar
刘乐 committed
264
{
刘乐's avatar
刘乐 committed
265 266 267
    map<string, int>::iterator iter = phenotype.begin();
    for (; iter != phenotype.end(); iter++)
    {
刘乐's avatar
刘乐 committed
268

刘乐's avatar
刘乐 committed
269
    }
270 271
}

刘乐's avatar
刘乐 committed
272
void GenAlg::decoding(vector<map<string, int>>& phenotype)
刘乐's avatar
刘乐 committed
273
{
刘乐's avatar
刘乐 committed
274 275 276 277 278 279 280 281 282 283 284 285
    size_t total = vecPop.size();
    
    for (int i = 0; i < total; i++)
    {
        Genome genome = vecPop[i];
        vector<char> genVec = genome.mBinaryGenVec;
        for (int j = 0; j < genVec.size(); j++)
        {
            phenotype[i].insert(pair<string, char>(mPumpBits[j], genVec[j]));
        }     
    }
}
刘乐's avatar
刘乐 committed
286

刘乐's avatar
刘乐 committed
287 288 289 290 291 292
void GenAlg::decodingSingle(vector<char>& chromo, map<string, int>& phenotype)
{
    for (int j = 0; j < chromo.size(); j++)
    {
        phenotype.insert(pair<string, char>(mPumpBits[j], chromo[j]));
    }
293 294 295 296 297 298 299 300 301 302
}

void GenAlg::setMaxMonitorVals(const  map<string, double>& maxMonitors)
{
    mOptScheduling->setMaxMonitorVals(maxMonitors);
}

void GenAlg::setMinMonitorsVals(const map<string, double>& minMonitors)
{
    mOptScheduling->setMinMonitorsVals(minMonitors);
刘乐's avatar
刘乐 committed
303 304 305 306 307
}

void GenAlg::setPumpBit(const vector<string>& pumpBit)
{
    mPumpBits = pumpBit;
刘乐's avatar
刘乐 committed
308
}