我撰寫的多目標微分進化演算法,用irank表示占優數,也就是(函式f1和f2的值都該陣列內其他成員的值都要笑),idist表示擁擠距離(按照f1函式值升序排列后,點i與其最近的點組成的矩形的邊長的一半),x和y代表二維空間兩個引數。思路是 初始化p1----計算idist和irank--突變操作生成trial--把P1和trial合并成p2---計算p2的irank和idist----選取irank大(優先選)和idist大(當irank相同時)---選取前NP個賦值給p1---輸出p1的fit1和fit2-計算idist和irank------回圈計算10次 目前問題是每次輸出的fit1和fit2都不變
非專業學生 最近學了點遍的 有點不規范 希望大家幫幫忙啊
#include <iostream>
#include <cmath>
#include <math.h>
#include <ctime>
#include <fstream>
using namespace std;
#define NP 10
#define NP2 2*NP
#define x_min 0.1
#define x_max 1
#define y_min 0
#define y_max 5
//產生亂數,亂數為(0.0,1.0)
double Rand_Double(void)
{
return static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
}
//測驗函式f1和f2
//引數個數為2
double f1(double x_1, double x_2)
{
return x_1;
}
double f2(double x_3, double x_4)
{
return (1 + x_4) / x_3;
}
//定義個體類,包含特性值
class individual
{
public:
double x, y;
double fit1, fit2;
int irank;
double idist;
void copy(individual b)
{
x = b.x;
y = b.y;
fit1 = b.fit1;
fit2 = b.fit2;
irank = b.irank;
idist = b.idist;
}
};
//定義交換函式
void swap(individual &eg_1, individual &eg_2)
{
individual temp_1;
temp_1.x = eg_1.x;
eg_1.x = eg_2.x;
eg_2.x = temp_1.x;
temp_1.y = eg_1.y;
eg_1.y = eg_2.y;
eg_2.y = temp_1.y;
temp_1.fit1 = eg_1.fit1;
eg_1.fit1 = eg_2.fit1;
eg_2.fit1 = temp_1.fit1;
temp_1.fit2 = eg_1.fit2;
eg_1.fit2 = eg_2.fit2;
eg_2.fit2 = temp_1.fit2;
temp_1.irank = eg_1.irank;
eg_1.irank = eg_2.irank;
eg_2.irank = temp_1.irank;
temp_1.idist = eg_1.idist;
eg_1.idist = eg_2.idist;
eg_2.idist = temp_1.idist;
}
//步驟2計算irank,此處采取回圈對比方式統計本身不被支配數目
void compute_irank(individual eg_3[], int n)
{
// for(int i=0;i<n;++i)
// eg_3[i].irank=0;
for (int i = 0; i<n; ++i)
for (int j = i; j<n; ++j)
{
if (eg_3[i].fit1 <= eg_3[j].fit1 && eg_3[i].fit2 <= eg_3[j].fit2) eg_3[i].irank = eg_3[i].irank + 1;
else if (eg_3[i].fit1 >= eg_3[j].fit1 && eg_3[i].fit2 >= eg_3[j].fit2) eg_3[j].irank = eg_3[j].irank + 1;
}
}
//按照f1進行升序排列
void sort(individual eg_4[], int n)
{
int i, j, p;
for (i = 0; i<n - 1; i++)
{
p = i;
for (j = i + 1; j<n; j++)
if (eg_4[j].fit1<eg_4[p].fit1) p = j;
if (p != i)
swap(eg_4[p], eg_4[i]);
}
}
//篩選下一代種群
void sort2(individual eg_8[], int n)
{
int i, j, p;
for (i = 0; i<n - 1; i++)
{
p = i;
for (j = i + 1; j<n; j++)
{
if (eg_8[j].irank == eg_8[p].irank)
{
if (eg_8[j].idist>eg_8[p].idist) p = j;
}
else if (eg_8[j].irank>eg_8[p].irank) p = j;
}
if (p != i)
swap(eg_8[p], eg_8[i]);
}
}
//find idist計算方式 兩點構成矩形的邊長的一般,選擇該點與其距離最近的鄰近點
void compute_idist(individual eg_5[], int n)
{
double temp_2, temp_3;
for (int i = 0; i<n - 1; ++i)
{
if (i == 1) eg_5[i].idist = sqrt((eg_5[i + 1].fit1 - eg_5[i].fit1)*(eg_5[i + 1].fit1 - eg_5[i].fit1)) + sqrt((eg_5[i + 1].fit2 - eg_5[i].fit2)*(eg_5[i + 1].fit2 - eg_5[i].fit2));
else if (i == n - 1) eg_5[n - 1].idist = sqrt((eg_5[i + 1].fit1 - eg_5[i].fit1)*(eg_5[i + 1].fit1 - eg_5[i].fit1)) + sqrt((eg_5[i + 1].fit2 - eg_5[i + 1].fit2)*(eg_5[i + 1].fit2 - eg_5[i + 1].fit2));
else
{
temp_2 = sqrt((eg_5[i].fit1 - eg_5[i - 1].fit1)*(eg_5[i].fit1 - eg_5[i - 1].fit1) + (eg_5[i].fit2 - eg_5[i - 1].fit2)*(eg_5[i].fit2 - eg_5[i - 1].fit2));
temp_3 = sqrt((eg_5[i + 1].fit1 - eg_5[i].fit1)*(eg_5[i + 1].fit1 - eg_5[i].fit1) + (eg_5[i + 1].fit2 - eg_5[i + 1].fit2)*(eg_5[i + 1].fit2 - eg_5[i + 1].fit2));
if (temp_2 >= temp_3) eg_5[i].idist = sqrt((eg_5[i + 1].fit1 - eg_5[i].fit1)*(eg_5[i + 1].fit1 - eg_5[i].fit1)) + sqrt((eg_5[i + 1].fit2 - eg_5[i].fit2)*(eg_5[i + 1].fit2 - eg_5[i].fit2));
else eg_5[i].idist = sqrt((eg_5[i].fit1 - eg_5[i - 1].fit1)*(eg_5[i].fit1 - eg_5[i - 1].fit1)) + sqrt((eg_5[i].fit2 - eg_5[i - 1].fit2)*(eg_5[i].fit2 - eg_5[i - 1].fit2));
}
}
}
void main()
{
//---------------------------設定亂數------------------------------------
srand((unsigned int)(time(NULL)));
//獲得引數
int Gen=10;
double F=0.5, cr=0.5;
int i;
individual *P1, *trial, *P2;
P1=new individual[NP];
trial=new individual[NP];
P2=new individual[NP2];
//-------------------------產生初始的隨機種群--------------------------------
for (i = 0; i<NP; ++i)//對種群進行遍歷
{
P1[i].x = Rand_Double()*(x_max - x_min) + x_min;
P1[i].y = Rand_Double()*(y_max - y_min) + y_min;
P1[i].fit1 = f1(P1[i].x, P1[i].y);
P1[i].fit2 = f2(P1[i].x, P1[i].y);
P1[i].idist = P1[i].irank = 0;
}
for (int t = 0; t<Gen; ++t)//開始一代一代地進化
{
srand((unsigned int)(time(NULL)));
//分別計算irank和idist
compute_irank(P1, NP);
sort(P1, NP);
compute_idist(P1, NP);
ofstream out3("trial.txt", ios::app);
//out<<endl;
out3 <<" begin--1"<< endl;
out3 << "fit1" << endl;
for (i = 0; i<NP; ++i)
out3 << P1[i].fit1 << '\t';
out3 << endl;
out3 << "fit2" << endl;
for (i = 0; i<NP; ++i)
out3 << P1[i].fit2 << '\t';
out3 << endl;
out3.close();
//差分變異
for (i = 0; i<NP; ++i)//對種群進行遍歷
{
//產生三個與i不同的亂數
int ran = 0;
ran = rand() % 2 + 1;
int r1, r2, r3;
do
{
r1 = rand() % NP;
} while (r1 == i);
do
{
r2 = rand() % NP;
} while (r1 == r2 || r2 == i);
do
{
r3 = rand() % NP;
} while (r1 == r3 || r2 == r3 || r3 == i);
trial[i].idist = trial[i].irank = 0;
if (Rand_Double()>cr && ran == 2) trial[i].x = P1[i].x;
else trial[i].x = P1[r1].x + F*(P1[r2].x - P1[r3].x);
if (Rand_Double()>cr && ran == 1) trial[i].y = P1[i].y;
else trial[i].y = P1[r1].y + F*(P1[r2].y - P1[r3].y);
if (trial[i].x<x_min )//越界
trial[i].x = (trial[i].x+x_min)*0.5;
if(trial[i].x>x_max)
trial[i].x = (trial[i].x-x_max)*0.5+x_min;
trial[i].y = P1[r1].y + F*(P1[r2].y - P1[r3].y);
if (trial[i].y<y_min )//越界
trial[i].y = (trial[i].y+y_min)*0.5;
if(trial[i].y>y_max)
trial[i].y= (trial[i].y-y_max)*0.5+y_min;
trial[i].fit1 = f1(trial[i].x, trial[i].y);
trial[i].fit2 = f2(trial[i].x, trial[i].y);
}
//擴充新的種群 P2
for (i = 0; i<NP2; ++i)
{
int t2;
t2 = i - NP;
if (i<NP) P2[i].copy(P1[i]);
else P2[i].copy(trial[t2]);
}
//分別計算irand和idist
compute_irank(P2, NP2);
sort(P2, NP2);
compute_idist(P2, NP2);
sort2(P2, NP2);
// xia yi dai
for (i = 0; i<NP; ++i)
P1[i].copy(P2[i]);
ofstream out("trial.txt", ios::app);
out << t << endl;
out << "fit1" << endl;
for (i = 0; i<NP; ++i)
out << P1[i].fit1 << '\t';
out << endl;
out << "fit2" << endl;
for (i = 0; i<NP; ++i)
out << P1[i].fit2 << '\t';
out << endl;
out.close();
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/120965.html
標籤:基礎類
