人工鱼群算法详见文献-李晓磊. 一种新型的智能优化方法-人工鱼群算法[D]. 杭州: 浙江大学, 2003. 基于侧向光散射,根本不同角度下的光能分布计算颗粒系粒径分布函数的两个参数。
#pragma once #include<vector> #include<iostream> #include<string> using namespace std; class fishswarm { public: fishswarm(int fishnum,int Maxgen,int trynumer,double visual,double delta,double step, int T_number, int D_number); ~fishswarm(); void file_to_string(vector<string> &record, const string& line, char delimiter); double string_to_float(string str); void ReadFile(string T_file_name,string Emes_file_name); double Normal(double x, double miu, double sigma); //概率密度函数 double FoodConsistence();//初始的所有浓度 real为测量值 double Dist(double Xi[1][2], vector<vector<double>> X, vector<vector<double>> &D); double singecon(double x1, double x2); double Prey(double Xi[1][2], int i, double visual, double step, double try_number, double FieldDR[2][2], vector<vector<double>>LastY, double XI1[1][2]); double Swarm(vector<vector<double>>Xi, int i, double visual, double step, double delta, double try_number, double FieldDR[2][2], vector<vector<double>>LastY, double XI1[1][2], double YI1); double Follow(vector<vector<double>>Xi, int i, double visual, double step, double delta, double try_number, double FieldDR[2][2], vector<vector<double>>LastY, double XI2[1][2], double YI2); double start(); private: int fishnum; int Maxgen; int trynumber; double visual; double delta; double step; double FieldDR[2][2]; int flag; int T_number; int D_number; vector<vector<double>>X; vector<vector<double>>E_mes;//光能分布测量值 vector<vector<double>>T; vector<vector<double>>Y; }; #include "fishswarm.h" #include "math.h" #include "time.h" #include<iostream> #include<stdlib.h> #include<fstream> #include<iomanip> #include <streambuf> #include<string> #include<vector> #include<algorithm> #include<numeric> #include <direct.h> #define M_PI 3.14159265358979323846 #include "ctime" const int N = 999; using namespace std; fishswarm::fishswarm(int fishnum, int Maxgen, int trynumer, double visual, double delta, double step,int T_number,int D_number) { X = vector<vector<double>>(fishnum, vector<double>(2)); Y = vector<vector<double>>(fishnum, vector<double>(1)); T = vector<vector<double>>(T_number, vector<double>(D_number,1)); E_mes = vector<vector<double>>(T_number, vector<double>(1)); this->fishnum = fishnum; this->Maxgen= Maxgen; this->trynumber = trynumber; this->visual = visual; this->delta = delta; this->step = step; this->T_number = T_number; this->D_number = D_number; FieldDR[0][0] = 0.1; FieldDR[0][1] = 3; FieldDR[1][0] = 15; FieldDR[1][1] = 15; double randnumber; srand((unsigned)time(NULL)); for (int i = 0; i < fishnum; i++) { randnumber = rand() % 100 / (double)101; X[i][0] = FieldDR[0][0] + (FieldDR[1][0] - FieldDR[0][0])*randnumber; } for (int i = 0; i < fishnum; i++) { randnumber = rand() % 100 / (double)101; X[i][1] = FieldDR[0][1] + (FieldDR[1][1] - FieldDR[0][1])*randnumber; } /*for (int i = 0; i < fishnum; i++) { for (int j = 0; j < 2; j++) { cout << X[i][j] << " "; } cout << endl; }*/ } fishswarm::~fishswarm() { } void fishswarm::file_to_string(vector<string> &record, const string& line, char delimiter) { int linepos = 0; char c; int linemax = line.length(); string curstring; record.clear(); while (linepos<linemax) { c = line[linepos]; if (isdigit(c) || c == '.') { curstring += c; } else if (c == delimiter&&curstring.size()) { record.push_back(curstring); curstring = ""; } ++linepos; } if (curstring.size()) record.push_back(curstring); return; } double fishswarm::string_to_float(string str) { int i = 0, len = str.length(); double sum = 0; while (i<len) { if (str[i] == '.') break; sum = sum * 10 + str[i] - '0'; ++i; } ++i; double t = 1, d = 1; while (i<len) { d *= 0.1; t = str[i] - '0'; sum += t*d; ++i; } return sum; } void fishswarm::ReadFile(string T_file_name, string Emes_file_name) { vector<string> row; vector<double>b; string line; string filename; char path_dir[255]; char p[] = { "\\" }; _getcwd(path_dir, sizeof(path_dir)); string dir; dir = path_dir; dir = dir + "\\" + T_file_name; ifstream in_T(dir); if (in_T.fail()) { cout << "File not found" << endl; return; } int i = 0; while (getline(in_T, line) && in_T.good()) { file_to_string(row, line, ','); for (int i = 0, leng = row.size(); i<leng; i++) { b.push_back(string_to_float(row[i])); } T[i] = b; b.clear(); i = i + 1; } in_T.close(); i = 0; vector<string> row1; vector<double>bb; string line1; string filename1; dir = path_dir; dir = dir + "\\" + Emes_file_name; ifstream in_E(dir); if (in_E.fail()) { cout << "File not found" << endl; return; } while (getline(in_E, line1) && in_E.good()) { file_to_string(row1, line1, ','); for (int i = 0, leng = row1.size(); i<leng; i++) { bb.push_back(string_to_float(row1[i])); } E_mes[i]=bb; i = i + 1; bb.clear(); } in_E.close(); } double fishswarm::Normal(double x, double miu, double sigma) { //return 0.1 / (sqrt(2 * M_PI)*sigma) * exp(-1 * (x - miu)*(x - miu) / (2 * sigma*sigma)); return 0.1*sigma / miu*pow(x / miu, sigma - 1)*exp(-pow(x / miu, sigma)); } double fishswarm::FoodConsistence() { int fnum = X.size(); vector<double>mu(fnum); vector<double>sig(fnum); vector<double>d(D_number); for (int i = 0; i < fnum; i++) { mu[i] = X[i][0]; sig[i] = X[i][1]; } double j = 0; for (int i = 0; i < D_number; i++) { d[i] = j + 0.1; j = j + 0.1; } vector<vector<double>>value(D_number, vector<double>(1)); vector<vector<double>>E_value(T_number, vector<double>(1)); double YYY = { 0 }; for (int i = 0; i < fnum; i++) { for (int jj = 0; jj < D_number; jj++) { value[jj][0] = Normal(d[jj], mu[i], sig[i]); } for (int p = 0; p < T_number; p++) { for (int q = 0; q < 1; q++) { for (int t = 0; t < D_number; t++) { E_value[p][q] += T[p][t] * value[t][q]; } } } double maxv = 0; for (int tt = 0; tt < T_number; tt++) { if (E_value[tt][0] > maxv) { maxv = E_value[tt][0]; } } for (int tt = 0; tt < T_number; tt++) { E_value[tt][0] = E_value[tt][0] / maxv; } for (int n = 0; n < T_number; n++) { YYY = YYY + (E_value[n][0] - E_mes[n][0])*(E_value[n][0] - E_mes[n][0]); } Y[i][0] = 1 / YYY; YYY = 0; for (int tt = 0; tt < T_number; tt++) { E_value[tt][0] = 0; } } return 0; } double fishswarm::Dist(double Xi[1][2], vector<vector<double>> X, vector<vector<double>> &D) { int fnum = X.size(); for (int j = 0; j < fnum; j++) { D[j][0] = sqrt(pow((Xi[0][0] - X[j][0]), 2) + pow(Xi[0][1] - X[j][1], 2)); } return 0; } double fishswarm::singecon(double x1, double x2) { vector<vector<double>>value(D_number, vector<double>(1)); vector<vector<double>>E_value(T_number, vector<double>(1)); vector<double>d(D_number); double jj = 0; for (int i = 0; i < D_number; i++) { d[i] = jj + 0.1; jj = jj + 0.1; } for (int i = 0; i < D_number; i++) { value[i][0] = Normal(d[i], x1, x2); } for (int p = 0; p < T_number; p++) { for (int q = 0; q < 1; q++) { for (int t = 0; t < D_number; t++) { E_value[p][q] += T[p][t] * value[t][q]; } } } double maxv = 0; for (int tt = 0; tt < T_number; tt++) { if (E_value[tt][0] > maxv) { maxv = E_value[tt][0]; } } for (int tt = 0; tt < T_number; tt++) { E_value[tt][0] = E_value[tt][0] / maxv; } double YYY = 0; for (int n = 0; n < T_number; n++) { YYY = YYY + (E_value[n][0] - E_mes[n][0])*(E_value[n][0] - E_mes[n][0]); } return 1 / YYY; } double fishswarm::Prey(double xi[1][2], int ii, double visual, double step, double try_number, double FieldDR[2][2], vector<vector<double>>LastY, double XI1[1][2]) { double Yi, Yj, Xj1, Xj2; double YYYY = { 0 }; Yi = LastY[ii][0]; srand((unsigned)time(NULL)); double randnumber; for (int i = 0; i < try_number; i++) { randnumber = rand() % 100 / (double)101; Xj1 = xi[0][0] + (2 * randnumber - 1)*visual; randnumber = rand() % 100 / (double)101; Xj2 = xi[0][1] + (2 * randnumber - 1)*visual; Yj = singecon(Xj1, Xj2); if (Yi < Yj) { randnumber = rand() % 100 / (double)101; XI1[0][0] = xi[0][0] + randnumber*step*(Xj1 - xi[0][0]) / sqrt(pow((Xj1 - xi[0][0]), 2) + pow((Xj2 - xi[0][1]), 2)); XI1[0][1] = xi[0][1] + randnumber*step*(Xj2 - xi[0][1]) / sqrt(pow((Xj1 - xi[0][0]), 2) + pow((Xj2 - xi[0][1]), 2)); for (int j = 0; j < 2; j++) { if (XI1[0][j] > FieldDR[1][j]) { XI1[0][j] = FieldDR[1][j]; } if (XI1[0][j] < FieldDR[0][j]) { XI1[0][j] = FieldDR[0][j]; } } break; } } if (XI1[0][0] == 0) { randnumber = rand() % 100 / (double)101; XI1[0][0] = xi[0][0] + (2 * randnumber - 1)*visual; randnumber = rand() % 100 / (double)101; XI1[0][1] = xi[0][1] + (2 * randnumber - 1)*visual; for (int j = 0; j < 2; j++) { if (XI1[0][j] > FieldDR[1][j]) { XI1[0][j] = FieldDR[1][j]; } if (XI1[0][j] < FieldDR[0][j]) { XI1[0][j] = FieldDR[0][j]; } } } YYYY = singecon(XI1[0][0], XI1[0][1]); return YYYY; } double fishswarm::Swarm(vector<vector<double>>X, int i, double visual, double step, double delta, double try_number, double FieldDR[2][2], vector<vector<double>>LastY, double XI1[1][2], double YI1) { int fnum = X.size(); double xi[1][2]; vector<vector<double>>D(fnum, vector<double>(1)); int jj = 0; double Yc = 0; double Yi; for (int p = 0; p < 2; p++) { xi[0][p] = X[i][p]; } Dist(xi, X, D); int number = 0; for (int j = 0; j < fnum; j++) { if (D[j][0]<visual) { number = number + 1; } } vector<int> index(number); vector<vector<double> > Xc(number); for (unsigned int j = 0; j < Xc.size(); j++) { Xc[j].resize(2); } for (int j = 0, kk = 0; j < fnum; j++) { if (D[j][0]<visual) { index[kk] = j; kk = kk + 1; } } if (number > 0) { for (int j = 0; j < number; j++) { for (int k = 0; k < 2; k++) { jj = index[j]; Xc[j][k] = X[jj][k]; } } double Xc1 = 0, Xc2 = 0;//两个优化参数 for (int j = 0; j < number; j++) { Xc1 = Xc1 + Xc[j][0] / number; Xc2 = Xc2 + Xc[j][1] / number; } Yc = singecon(Xc1, Xc2); Yi = LastY[i][0]; srand((unsigned)time(NULL)); double randnumber; if (Yc / number > delta*Yi) { randnumber = rand() % 100 / (double)101; XI1[0][0] = xi[0][0] + randnumber*step*(Xc1 - xi[0][0]) / sqrt(pow((Xc1 - xi[0][0]), 2) + pow((Xc2 - xi[0][1]), 2)); XI1[0][1] = xi[0][1] + randnumber*step*(Xc2 - xi[0][1]) / sqrt(pow((Xc1 - xi[0][0]), 2) + pow((Xc2 - xi[0][1]), 2)); for (int j = 0; j < 2; j++) { if (XI1[0][j] > FieldDR[1][j]) { XI1[0][j] = FieldDR[1][j]; } if (XI1[0][j] < FieldDR[0][j]) { XI1[0][j] = FieldDR[0][j]; } } YI1 = singecon(XI1[0][0], XI1[0][1]); } else { YI1 = Prey(xi, i, visual, step, try_number, FieldDR, LastY, XI1); } } else { YI1 = Prey(xi, i, visual, step, try_number, FieldDR, LastY, XI1); } return YI1; } double fishswarm::Follow(vector<vector<double>>X, int i, double visual, double step, double delta, double try_number, double FieldDR[2][2], vector<vector<double>>LastY, double XI2[1][2], double YI2) { int fnum = X.size(); vector<vector<double>>D(fnum, vector<double>(1)); double xi[1][2]; int jj = 0; double Yc = 0; double Yi; for (int p = 0; p < 2; p++) { xi[0][p] = X[i][p]; } Dist(xi, X, D); int number = 0; for (int j = 0; j < fnum; j++) { if (D[j][0]<visual) { number = number + 1; } } vector<int> index(number); vector<vector<double> > Xc(number); vector<vector<double> > YY(number); for (unsigned int j = 0; j <YY.size(); j++) { YY[j].resize(1); } for (unsigned int j = 0; j < Xc.size(); j++) { Xc[j].resize(2); } for (int j = 0, kk = 0; j < fnum; j++) { if (D[j][0]<visual) { index[kk] = j; kk = kk + 1; } } if (number > 0) { for (int j = 0; j < number; j++) { for (int k = 0; k < 2; k++) { jj = index[j]; Xc[j][k] = X[jj][k]; } } for (int j = 0; j < number; j++) { YY[j][0] = singecon(Xc[j][0], Xc[j][1]); } int max_index; double Ymax = 0; double Xmax1, Xmax2; for (int j = 0; j < number; j++) { if (YY[j][0] > Ymax) { max_index = j; Ymax = YY[j][0]; } } Xmax1 = Xc[max_index][0]; Xmax2 = Xc[max_index][1]; Yi = LastY[i][0]; srand((unsigned)time(NULL)); double randnumber; if (Ymax / number > delta*Yi) { randnumber = rand() % 100 / (double)101; XI2[0][0] = xi[0][0] + randnumber*step*(Xmax1 - xi[0][0]) / sqrt(pow((Xmax1 - xi[0][0]), 2) + pow((Xmax2 - xi[0][1]), 2)); XI2[0][1] = xi[0][1] + randnumber*step*(Xmax1 - xi[0][1]) / sqrt(pow((Xmax1 - xi[0][0]), 2) + pow((Xmax2 - xi[0][1]), 2)); for (int j = 0; j < 2; j++) { if (XI2[0][j] > FieldDR[1][j]) { XI2[0][j] = FieldDR[1][j]; } if (XI2[0][j] < FieldDR[0][j]) { XI2[0][j] = FieldDR[0][j]; } } YI2 = singecon(XI2[0][0], XI2[0][1]); } else { YI2 = Prey(xi, i, visual, step, try_number, FieldDR, LastY, XI2); } } else { YI2 = Prey(xi, i, visual, step, try_number, FieldDR, LastY, XI2); } return YI2; } double fishswarm::start() { vector<vector<double>>BestX(Maxgen + 1, vector<double>(2)); vector<vector<double>>BestY(Maxgen + 1, vector<double>(1)); int gen = 0; double besty = 0; double bestx[1][2]; double XI1[1][2] = { 0 }; double YI1 = { 0 }; double XI2[1][2] = { 0 }; double YI2 = { 0 }; clock_t startTime, endTime; startTime = clock(); while (gen <= Maxgen) { for (int i = 0; i < fishnum; i++) { YI1 = Swarm(X, i, visual, step, delta, trynumber, FieldDR, Y, XI1, YI1); YI2 = Follow(X, i, visual, step, delta, trynumber, FieldDR, Y, XI2, YI2); if (YI1 > YI2) { X[i][0] = XI1[0][0]; X[i][1] = XI1[0][1]; Y[i][0] = YI1; } else { X[i][0] = XI2[0][0]; X[i][1] = XI2[0][1]; Y[i][0] = YI2; } } int max_index; double Y_max = 0; for (int j = 0; j <fishnum; j++) { if (Y[j][0] > Y_max) { max_index = j; Y_max = Y[j][0]; } } if (Y_max > besty) { besty = Y_max; bestx[0][0] = X[max_index][0]; bestx[0][1] = X[max_index][1]; BestY[gen][0] = Y_max; BestX[gen][0] = X[max_index][0]; BestX[gen][1] = X[max_index][1]; } else { BestY[gen][0] = BestY[gen - 1][0]; BestX[gen][0] = BestX[gen - 1][0]; BestX[gen][1] = BestX[gen - 1][1]; } cout << BestX[gen][0] << " "; cout << BestX[gen][1] << " "; cout << BestY[gen][0] << endl; gen = gen + 1; cout << gen << endl; } endTime = clock(); cout << "The run time is:" << (double)clock() / CLOCKS_PER_SEC << "s" << endl; ofstream outfile; outfile.open("dir\\filename.txt"); outfile << "bestx1" << " "; outfile << "bestx2" << " "; outfile << "besty" << endl; for (int i = 0; i < gen; i++) { outfile << BestX[i][0] << " "; outfile << BestX[i][1] << " "; outfile << BestY[i][0] << endl; } outfile.close(); cout << bestx[0][0] << " " << bestx[0][1] << endl; double j = 0; double D[200] = { 0 }; double dis[200]; double a = 0; for (int i = 0; i < 200; i++) { D[i] = j + 0.1; j = j + 0.1; } for (int i = 0; i < 200; i++) { dis[i] = Normal(D[i], bestx[0][0], bestx[0][1]); a = a + dis[i]; cout << D[i] << " " << dis[i] * 100 << endl; } cout << a; return 0; }