Evacloud
- 在EC算法比较结果时一般使用20次运算得到的平均值,并且IGD的迭代曲线也是20次的平均值,这里我们想将得到的IGD的每次迭代的平均值保存下来。使用jmetal实现。
int times = 20;
//创建列表数组
ArrayList<Integer>[] Time_no_evas = new ArrayList[times];
ArrayList<Double>[] Time_IGD1 = new ArrayList[times];
ArrayList<Double>[] Time_IGD2 = new ArrayList[times];
for (int i = 0; i < times; i ) {
//java中这里必须要对于每一个数组地址下的链表,再构建一个链表,否则返回空,这里与c 不同
ArrayList<Integer> a = new ArrayList<>();
ArrayList<Double> b = new ArrayList<>();
ArrayList<Double> c = new ArrayList<>();
Time_no_evas[i] = a;
Time_IGD1[i] = b;
Time_IGD2[i] = c;
}
for (int t = 1; t <= times; t ) {
SolutionSet population = algorithm.execute();
Time_no_evas[t - 1] = (ArrayList<Integer>)((NMOMFESV1) algorithm).no_evas.clone();
Time_IGD1[t - 1] = (ArrayList<Double>) ((NMOMFESV1) algorithm).IGD1.clone();
Time_IGD2[t - 1] = (ArrayList<Double>)((NMOMFESV1) algorithm).IGD2.clone();
}
//计算Times过程IGD的平均值
//求长度
int num_inter = Time_no_evas[0].size();//这是time中总共迭代的次数
double[] aver_time_igd1 = new double[num_inter];
double[] aver_time_igd2 = new double[num_inter];
aver_IGD(num_inter, times, Time_IGD1, aver_time_igd1);
aver_IGD(num_inter, times, Time_IGD2, aver_time_igd2);
String root = System.getProperty("user.dir");
String OutputFileName = "averIGD.csv";
String OutputfilePath = root File.separator "log" File.separator name1 File.separator "MOMFES" File.separator "IGD" File.separator save_as_name File.separator OutputFileName;
writeaverIGD(((NMOMFESV1) algorithm).no_evas, aver_time_igd1, aver_time_igd2, OutputfilePath);
public static void aver_IGD(int num_inter, int times, ArrayList<Double>[] Time_IGD, double[] aver_time_igd) {
for (int i = 0; i < num_inter; i ) {
double total_igd = 0;
double aver_igd;
for (int j = 0; j < times; j ) {
total_igd = total_igd Time_IGD[j].get(i);
}
aver_igd = total_igd / times;
aver_time_igd[i] = aver_igd;
}
}
public static void writeaverIGD(ArrayList<Integer> NO, double[] IGD1, double[] IGD2, String path) {
try {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path), "UTF-8"));
for (int i = 0; i < NO.size(); i ) {
out.write(NO.get(i).toString());
out.write(",");
out.write(Double.toString(IGD1[i]));
out.write(",");
out.write(Double.toString(IGD2[i]));
out.newLine();
}
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
- 其中需要重点注意的是关于每次读的值的保存,应该将值直接保存,或者使用clone函数,而不能直接将地址传进去
- 例如以下写法就是正确的
for (int t = 1; t <= times; t ) {
SolutionSet population = algorithm.execute();
Time_no_evas[t - 1] = (ArrayList<Integer>)((NMOMFESV1) algorithm).no_evas.clone();
Time_IGD1[t - 1] = (ArrayList<Double>) ((NMOMFESV1) algorithm).IGD1.clone();
Time_IGD2[t - 1] = (ArrayList<Double>)((NMOMFESV1) algorithm).IGD2.clone();
}
- 但是以下写法就是错误的
for (int t = 1; t <= times; t ) {
SolutionSet population = algorithm.execute();
Time_no_evas[t - 1] = (ArrayList<Integer>)((NMOMFESV1) algorithm).no_evas;
Time_IGD1[t - 1] = (ArrayList<Double>) ((NMOMFESV1) algorithm).IGD1;
Time_IGD2[t - 1] = (ArrayList<Double>)((NMOMFESV1) algorithm).IGD2;
}
- 随着t的变化,Time_no_evas[0][1]..[n]指向的地址都是(ArrayList)((NMOMFESV1) algorithm).no_evas,最终会导致其中的结果都是最后一次的结果,也就是t=times得到的结果,而计算不出正确的平均值。因此这个地方应该改变的是列表数组中的值而不是单纯用指针指向这个地方。