#include<stdio.h>
#include <fstream>
#include<iostream>
#include <algorithm>
#include<string>
#include<direct.h>
#include<vector>
#define INSTANCE_NUM 7
#define RUN_TIMES 10
#define ALG_NUM 2
#define OBJ_NUM 2
#define eps 1e-8
using namespace std;
struct Chromosome { //解
double f[OBJ_NUM]; //5个目标值,f[0]:车辆数目,f[1]:总行驶距离;f[2]:长路径行驶时间;f[3]:总等待时间;f[4]:总延迟时间
double unit_f[OBJ_NUM]; //均衡化的5个目标
double min_dis;
};
int indi_num;
vector<Chromosome> EP;
vector<Chromosome> total_best;
vector<vector<Chromosome>> algSets[ALG_NUM];
bool is_dominate(Chromosome & s1, Chromosome & s2) {
if ((int)(s1.f[0] / 100000) < (int)(s2.f[0] / 100000)) {
return true;
}
if ((int)(s1.f[0] / 100000) > (int)(s2.f[0] / 100000)) {
return false;
}
if (s1.f[1] > s2.f[1] + eps || s1.f[0] > s2.f[0] + eps) {
return false;
}
return (s1.f[1] + eps < s2.f[1] || s1.f[0] + eps < s2.f[0]);
}
bool is_the_same(Chromosome & s1, Chromosome & s2) {
return (fabs(s1.f[1] - s2.f[1]) < eps && fabs(s1.f[0] - s2.f[0]) < eps);
}
void update_EP(Chromosome &indi) {
//检查是否被存档内的其他解占优
int size = EP.size(), i = 0;
while (i < size)
{
if (is_dominate(EP[i], indi) || is_the_same(EP[i], indi))
return;
if (is_dominate(indi, EP[i])) {
EP[i] = EP.back();
EP.pop_back();
--size;
}
else
i++;
}//s不被存档中的元素占优,将它加入存档__archive
//将节点加入存档
EP.push_back(indi);
}
void get_pareto_front(string path) {
string name;
for (int j = 0; j < RUN_TIMES; j++) {
name = path + "_run_0" + char(j + '0') + "_obj.txt";
fstream r_result(name, ios::in);
r_result >> indi_num;
for (int i = 0; i < indi_num; i++) {
Chromosome chrom;
for (int j = 0; j < OBJ_NUM; j++)
r_result >> chrom.f[j];
update_EP(chrom);
}
r_result.close();
}
}
bool is_better(Chromosome &chrome_1, Chromosome &chrome_2) {
bool better = false;
for (int i = 0; i < OBJ_NUM; ++i) {
if (chrome_2.f[i] - chrome_1.f[i] >= 0.000001)
better = true;
if (chrome_1.f[i] - chrome_2.f[i] > 0.000001)
return false; //只要chrome_1的关联矩阵有一个方向比旧解大,chrome_1是坏的,chrome_2有可取之处,返回false
}//chrome_2的关联矩阵的值都大于chrome_1,better = true,chrome_1是好的,chrome_2是坏的
return better;
}
/*判断存档中的解与新解是否相等
chrome_1:存档中的解;
chrome_2:新解
只要两个解的某一方向的值大于0.00001,两个解就不相等。返回false
其它返回true
*/
bool is_equal(Chromosome &chrome_1, Chromosome &chrome_2) {
for (int i = 0; i < OBJ_NUM; ++i) {
if (fabs(chrome_1.f[i] - chrome_2.f[i]) > 0.000001) return false; //只要两个解的某一方向的值大于0.00001,两个解就不相等。返回false
}
return true;
}
bool update_best(Chromosome &new_chromosome) {
if (total_best.size() == 0)
total_best.push_back(new_chromosome);
else {
//将存档EP中的解与new_chromosome进行比较
vector<Chromosome>::iterator iter = total_best.begin();
for (; iter != total_best.end(); ++iter) {
//将容器中的所有iter与new_chromosome比较,iter是否优于new_chromosome || iter与chomosome是否相等
if (is_better(*iter, new_chromosome) || is_equal(*iter, new_chromosome))
return false;
}//new_chromosome优于EP中所有的解
//从EP中去除劣于new_chromosome的解
iter = total_best.begin();
while (iter != total_best.end()) {
if (is_better(new_chromosome, *iter)) iter = total_best.erase(iter);
else ++iter;
}
//将new_chromosome加入占优解集
total_best.push_back(new_chromosome);
}
return true;
}
bool cmp1(Chromosome a, Chromosome b) {
return a.f[0] < b.f[0] || (a.f[0] == b.f[0] && a.f[1] < b.f[1]);
}
/*
M-NSGA-II\ MTEA\
*/
void main(int argc, char **argv) {
string instance[INSTANCE_NUM] = { "E051-05e","E076-10e","E101-08e","E101-10c","E121-07c","E151-12c","E200-17c" };
string name;
// 10 run for each instances
for (int i = 0; i < INSTANCE_NUM; i++) { //案例数目
for (int a = 0; a < ALG_NUM; a++) { //对比算法的数目
EP.clear();
string path = argv[a + 1] + instance[i];
for (int j = 0; j < RUN_TIMES; j++) {
name = path + "_run_0" + char(j + '0') + "_obj.txt";
fstream r_result(name, ios::in);
r_result >> indi_num;
for (int k = 0; k < indi_num; k++) {
Chromosome chrom;
for (int o = 0; o < OBJ_NUM; o++)
r_result >> chrom.f[o];
update_EP(chrom);
}
r_result.close();
}
//遍历EP,求2个算法的pareto 前沿
algSets[a].push_back(EP);
}
total_best.clear();
for (int a = 0; a < ALG_NUM; a++) {
for (int j = 0; j < algSets[a][i].size(); j++) {
update_best(algSets[a][i][j]);
}
}
sort(total_best.begin(),total_best.end(),cmp1);
string str = to_string(i);
FILE *file_pf = fopen(("front\\" + str + ".txt").c_str(), "w");
fprintf(file_pf, "%d\n", total_best.size());
for (int i = 0; i < total_best.size(); i++)
{
fprintf(file_pf, "%.8lf %.8lf\n", total_best[i].f[0], total_best[i].f[1]);
}
fclose(file_pf);
}
}