免疫优化算法在物流配送中心选址中的应用 C++ 实现
简介
为了完成老师布置的作业,找了一个案例来自《matlab智能算法30个案例》,选了免疫优化算法在物流配送中心选址中的应用,因为要求用C/C++写,但是在网上翻遍都没有相应的代码,所以只能自己动手了,上代码。
头文件mainyi.h
#include<vector>
using namespace std;
typedef struct
{
vector<int> fitness;
vector<double> concentration;
vector<double> excellence;
vector<vector<int>> chroms;
}population;
void popinit(vector<vector<int>>& chrom,int M, int length);
int fitness(vector<int>& chrom, vector<vector<int>> city_coordinate);
int loadData(vector<vector<int>>& city_coordinate);
double concentration(int target, int M, vector<vector<int>> individuals);
void excellence(population& individuals, int M, int ps);
population bestselect(population individuals, int M, int overbest);
population select(population individuals, int sizepop);
vector<vector<int>> cross(double pcross, vector<vector<int>> chroms, int sizepop, int length);
vector<vector<int>> mutate(double pmutation, vector<vector<int>> chroms, int sizepop, int length,int city_num);
population incorporate(population individuals, int sizepop, population bestindividuals, int overbest);
main函数
#include<iostream>
#include<fstream>
#include<vector>
#include"mianyi.h"
#include<string>
#include<algorithm>
#include<numeric>
#include<Windows.h>
using namespace std;
int sizepop = 10;
int overbest = 10;
int MAXGEN = 1000;
double pcross = 0.5;
double pmutation = 0.4;
double ps = 0.95;
int length = 6;
int M = sizepop + overbest;
vector<vector<int>> city_coordinate;
vector<vector<double>> trace;
int main() {
population individuals;
popinit(individuals.chroms,M,length);
for (int i = 0; i < M; i++) {
for (int j = 0; j < length; j++) {
cout << individuals.chroms[i][j]<<" ";
}
cout << endl;
}
loadData(city_coordinate);
for (int i = 0; i < MAXGEN; i++) {
for (int j = 0; j < M; j++) {
individuals.fitness.push_back(fitness(individuals.chroms[j], city_coordinate));
individuals.concentration.push_back(concentration(j, M, individuals.chroms));
}
excellence(individuals,M,ps);
vector<int>:: iterator bestChrom_fit = min_element(begin(individuals.fitness),end(individuals.fitness));
int bestChrom_idx = distance(begin(individuals.fitness), bestChrom_fit);
vector<int> bestChrom = individuals.chroms[bestChrom_idx];
double population_mean = accumulate(begin(individuals.fitness), end(individuals.fitness), 0.0) / individuals.fitness.size();
vector<double> v;
v.push_back(*bestChrom_fit); v.push_back(population_mean);
trace.push_back(v);
cout << "no." << i << " bestChrom_fit is " << *bestChrom_fit << " mean_fitness is "<<population_mean<<endl;
cout << "bestChrom is ";
for (int j = 0; j < bestChrom.size(); j++) {
cout << bestChrom[j] << ",";
}
cout << endl<<endl;
population bestindividuals;
bestindividuals = bestselect(individuals, M, overbest);
individuals = bestselect(individuals, M, sizepop);
individuals = select(individuals,sizepop);
individuals.chroms = cross(pcross, individuals.chroms, sizepop, length);
individuals.chroms = mutate(pmutation, individuals.chroms, sizepop, length, city_coordinate.size());
individuals = incorporate(individuals, sizepop, bestindividuals, overbest);
cout << "==========种群=============\n";
for (int i = 0; i < sizepop; i++) {
for (int j = 0; j < length; j++) {
cout << individuals.chroms[i][j] << " ";
}
cout << endl;
}
}
return 0;
}
popinit函数
#include<vector>
#include<time.h>
#include<Windows.h>
#include"mianyi.h"
#include<iostream>
using namespace std;
void popinit(vector<vector<int>>& chroms, int M, int length) {
srand((unsigned)time(0));
Sleep(1000);
for (int i = 0; i < M; i++) {
vector<int> v;
for (int j = 0; j < length; j++) {
if (j == 0) {
int city_num0 = rand() % 31;
v.push_back(city_num0);
continue;
}
vector<int>::iterator it;
int city_num;
do {
city_num = rand() % 31;
it = find(v.begin(), v.end(), city_num);
} while (it != v.end());
v.push_back(city_num);
}
chroms.push_back(v);
}
}
loadData函数
#include<vector>
#include<string>
#include<iostream>
#include<fstream>
using namespace std;
int loadData(vector<vector<int>>& city_coordinate) {
char strFilename[100];
string line;
cout << "|=========用鼠标拖入城市坐标文件,按回车键。=======|" << endl;
gets_s(strFilename);
ifstream File(strFilename);
if (!File.is_open())
{
cout << "can not open this file" << endl;
return 0;
}
while (getline(File, line)) {
vector<int> v;
string str1, str2;
int index;
line += '\n';
for (index = 0; line[index] != ','; index++) {
str1 += line[index];
}
index++;
for (; line[index] != '\n'; index++) {
str2 += line[index];
}
v.push_back(atoi(str1.c_str()));
v.push_back(atoi(str2.c_str()));
city_coordinate.push_back(v);
}
}
loadData函数
#include<vector>
#include<string>
#include<iostream>
#include<fstream>
using namespace std;
int loadData(vector<vector<int>>& city_coordinate) {
char strFilename[100];
string line;
cout << "|=========用鼠标拖入城市坐标文件,按回车键。=======|" << endl;
gets_s(strFilename);
ifstream File(strFilename);
if (!File.is_open())
{
cout << "can not open this file" << endl;
return 0;
}
while (getline(File, line)) {
vector<int> v;
string str1, str2;
int index;
line += '\n';
for (index = 0; line[index] != ','; index++) {
str1 += line[index];
}
index++;
for (; line[index] != '\n'; index++) {
str2 += line[index];
}
v.push_back(atoi(str1.c_str()));
v.push_back(atoi(str2.c_str()));
city_coordinate.push_back(v);
}
}
fitness函数
#include"mianyi.h"
#include<iostream>
#include<vector>
#include <string>
#include<fstream>
#include<math.h>
#define MAX_DIS 1000000
#define E 2.718281828459
using namespace std;
int fitness(vector<int>& chrom,vector<vector<int>> city_coordinate) {
int carge[] = { 20,90,90,60,70,70,40,90,90,70,60,40,40,40,20,80,90,70,100,50,50,50,80,70,80,40,40,60,70,50,30 };
vector<vector<int>> distance;
vector<vector<int>> min_distance;
for (int i = 0; i < city_coordinate.size(); i++) {
int min = MAX_DIS, index;
vector<int> v;
vector<int> min_v;
for (int j = 0; j < chrom.size(); j++) {
int dis = sqrt(pow(city_coordinate[i][0] - city_coordinate[chrom[j]][0], 2) + pow(city_coordinate[i][1] - city_coordinate[chrom[j]][1], 2));
if (dis < min ) {
min = dis;
index = chrom[j];
}
v.push_back(dis);
}
min_v.push_back(min); min_v.push_back(index);
distance.push_back(v);
min_distance.push_back(min_v);
}
double expense = 0.0;
for (int i = 0; i < city_coordinate.size(); i++) {
expense += carge[i] * min_distance[i][0];
}
int record_3000=0;
for (int i = 0; i < min_distance.size(); i++) {
if (min_distance[i][0] > 3000) record_3000++;
}
double fit = expense + 4.0 * E + 4 * record_3000;
return fit;
}
concentration函数
#include<vector>
using namespace std;
double similarity(vector<int> chrom_target, vector<int> chrom_other) {
double res = 0.0;
for (int i = 0; i < chrom_target.size(); i++) {
for (int j = 0; j < chrom_other.size(); j++) {
if (chrom_other[j] == -1) continue;
if (chrom_target[i] == chrom_other[j]) {
res++;
chrom_other[j] = -1;
break;
}
}
}
return res / chrom_target.size();
}
double concentration(int target,int M,vector<vector<int>> chroms) {
double concentration = 0.0;
for (int i = 0; i < M; i++) {
double xsd = similarity(chroms[target],chroms[i]);
if (xsd > 0.5) concentration += 1;
}
return concentration/M;
}
excellence函数
#include<vector>
#include "mianyi.h"
using namespace std;
void excellence(population& individuals, int M, int ps) {
double sumfit = 0.0;
for (int i = 0; i < individuals.fitness.size(); i++) {
sumfit += 1.0 / individuals.fitness[i];
}
double sumcon = 0.0;
for (int i = 0; i < individuals.concentration.size(); i++) {
sumcon += individuals.concentration[i];
}
for (int i = 0; i < M; i++) {
double exc = 1.0 / individuals.fitness[i] / sumfit * ps + individuals.concentration[i] / sumcon * (1 - ps);
individuals.excellence.push_back(exc);
}
}
bestselect函数
#include "mianyi.h"
#include<algorithm>
#include<iostream>
#include<map>
typedef pair<int, int> PAIR;
typedef pair<int, double> PAIR2;
bool cmp(const PAIR& left, const PAIR& right) {
return left.second < right.second;
}
bool cmp2(const PAIR2& left, const PAIR2& right) {
return left.second > right.second;
}
population bestselect(population individuals, int M, int _size) {
population ret; int s = 3;
map<int, int> map_fit;
for (int i = 0; i < individuals.fitness.size(); i++) {
map_fit[i] = individuals.fitness[i];
}
vector<PAIR> vec_fit(map_fit.begin(), map_fit.end());
sort(vec_fit.begin(), vec_fit.end(),cmp);
for (int i = 0; i < s; i++) {
ret.fitness.push_back( individuals.fitness[vec_fit[i].first]);
ret.concentration.push_back( individuals.concentration[vec_fit[i].first]);
ret.excellence.push_back( individuals.excellence[vec_fit[i].first]);
ret.chroms.push_back(individuals.chroms[vec_fit[i].first]);
}
population remain_individuals;
for (int j = s; j < M; j++) {
remain_individuals.fitness.push_back(individuals.fitness[vec_fit[j].first]);
remain_individuals.concentration.push_back(individuals.concentration[vec_fit[j].first]);
remain_individuals.excellence.push_back(individuals.excellence[vec_fit[j].first]);
remain_individuals.chroms.push_back(individuals.chroms[vec_fit[j].first]);
}
map<int, double> map_exc;
for (int i = 0; i < remain_individuals.excellence.size(); i++) {
map_exc[i] = remain_individuals.excellence[i];
}
vector<PAIR2> vec_exc(map_exc.begin(), map_exc.end());
sort(vec_exc.begin(), vec_exc.end(), cmp2);
for (int i = s; i < _size; i++) {
ret.fitness.push_back(remain_individuals.fitness[vec_exc[i - s].first]);
ret.concentration.push_back(remain_individuals.concentration[vec_exc[i - s].first]);
ret.excellence.push_back(remain_individuals.excellence[vec_exc[i - s].first]);
ret.chroms.push_back(remain_individuals.chroms[vec_exc[i - s].first]);
}
return ret;
}
select函数
#include "mianyi.h"
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(double a, double b) {
return a > b;
}
population select(population individuals, int sizepop) {
population ret;
vector<double> excellence = individuals.excellence;
double exc_sum = 0.0;
for (int i = 0; i < excellence.size(); i++) {
exc_sum += excellence[i];
}
vector<double> pselect;
for (int i = 0; i < excellence.size(); i++) {
pselect.push_back(excellence[i] / exc_sum);
}
sort(pselect.begin(), pselect.end(), cmp);
vector<int> index;
for (int i = 0; i < sizepop; i++) {
double pick = rand() % 100 / 100.0;
while (pick == 0) {
pick = rand() % 100 / 100.0;
}
for (int j = 0; j < sizepop; j++) {
pick -= pselect[j];
if (pick < 0) {
index.push_back(j);
break;
}
}
}
for (int i = 0; i < index.size(); i++) {
ret.chroms.push_back(individuals.chroms[index[i]]);
ret.fitness.push_back(individuals.fitness[index[i]]);
ret.concentration.push_back(individuals.concentration[index[i]]);
ret.excellence.push_back(individuals.excellence[index[i]]);
}
return ret;
}
cross函数
#include<vector>
#include<set>
using namespace std;
bool validate(vector<int> chrom) {
set<int> s;
for (vector<int>::iterator it = chrom.begin(); it != chrom.end(); it++) {
s.insert(*it);
}
if (s.size() < chrom.size()) {
return false;
}
return true;
}
vector<vector<int>> cross(double pcross, vector<vector<int>> chroms,int sizepop,int length) {
for (int i = 0; i < sizepop; i++) {
double pick = rand() % 101 / 100.0;
while (pick == 0) {
pick = rand() % 101 / 100.0;
}
if (pick > pcross) {
continue;
}
int chrom_index1 = rand() % sizepop;
int chrom_index2 = rand() % sizepop;
while (chrom_index1 == chrom_index2) {
chrom_index2 = rand() % sizepop;
}
vector<int> chrom1 = chroms[chrom_index1];
vector<int> chrom2 = chroms[chrom_index2];
int pos = rand() % length;
while (pos == 0) {
pos = rand() % length;
}
vector<int> temp;
for (int i = pos; i < length; i++) {
temp.push_back(chrom1[i]);
}
for (int i = pos; i < length; i++) {
chrom1[i] = chrom2[i];
}
for (int i = pos; i < length; i++) {
chrom2[i] = temp[i - pos];
}
temp.clear();
if (validate(chrom1) || validate(chrom2)) {
continue;
}
chroms[chrom_index1] = chrom1;
chroms[chrom_index2] = chrom2;
}
return chroms;
}
mutate函数
#include<vector>
#include<set>
#include "mianyi.h"
using namespace std;
vector<vector<int>> mutate(double pmutation, vector<vector<int>> chroms, int sizepop,int length,int city_num) {
for (int i = 0; i < sizepop; i++) {
double pick = rand() % 101 / 100.0;
while (pick == 0) {
pick = rand() % 101 / 100.0;
}
if (pick > pmutation) {
continue;
}
int chrom_index = rand() % sizepop;
vector<int> chrom = chroms[chrom_index];
int pos = rand() % length;
chrom[pos] = rand() % city_num;
set<int> s;
for (vector<int>::iterator it=chrom.begin(); it != chrom.end(); it++) {
s.insert(*it);
}
while (s.size() == length - 1) {
chrom[pos] = rand() % city_num;
for (vector<int>::iterator it = chrom.begin(); it != chrom.end(); it++) {
s.insert(*it);
}
}
chroms[chrom_index] = chrom;
}
return chroms;
}
incorporate函数
#include "mianyi.h"
population incorporate(population individuals, int sizepop, population bestindividuals, int overbest) {
population newIndividual;
int M = sizepop + overbest;
for (int i = 0; i < sizepop; i++) {
newIndividual.chroms.push_back(individuals.chroms[i]);
}
for (int i = sizepop; i < M; i++) {
newIndividual.chroms.push_back(bestindividuals.chroms[i- sizepop]);
}
return newIndividual;
}
结果
 运行了很多次,最优抗体的适应度是548960,最优染色体组成是4,8,11,16,26,但是容易局部收敛于553480,组成4,8,11,17,24,26
|