MATP ManyTask Multitask Problem和Solution的变量范围
觉得有用的话,欢迎一起讨论相互学习~
参考文献
https://blog.csdn.net/u013555719/article/details/103569252
https://blog.csdn.net/u013555719/article/details/103595998
我们知道在多个任务一起优化的时候,任务即Problem有不同的变量范围,但是在多任务优化中我们需要使用相同的决策变脸对其进行表示而在解决问题时又要将其映射回自身的空间。
- 因此在MMDTLZ问题evalute函数的第一句即会调用Problem类的scaleVariables函数
public void evaluate(Solution solution) throws JMException {
double vars[] = scaleVariables(solution);
Problem类中的scaleVariable函数
我认为这个函数在使用同一个Problem初始化的solution解决这个任务不会有任何问题,只有在初始化solution的problem和需要解决的problem之间决策变量范围不同的情况下,也就是说在迁移的过程中,这个函数才会发生作用.
protected double[] scaleVariables(Solution solution) throws JMException {
Variable[] decisionVariables = solution.getDecisionVariables();
double[] x = new double[numberOfVariables_];
for (int i = 0; i < numberOfVariables_; i++)
x[i] = decisionVariables[i].getValue();
for (int i = 0; i < numberOfVariables_; i++) {
double sl = decisionVariables[i].getLowerBound();
double su = decisionVariables[i].getUpperBound();
double pl = lowerLimit_[i];
double pu = upperLimit_[i];
x[i] = ((x[i] - sl) * (pu - pl)) / (su - sl) + pl;
}
return x;
}
注意scaleVariable函数是protected属性的,因此此处我们做外部测试时需要将其修改为public权限。
测试
1. 使用MATP1和MATP3测试集
ProblemSet matp1;
ProblemSet matp3;
matp1 = MATP1.getProblem();
matp3 = MATP3.getProblem();
2. 使用MATP1初始化SolutionSet testSSvarMATP1
SolutionSet testSSvarMATP1 = new SolutionSet();
//初始化示例化的Solution
tools.InibasictestSolSet(testSSvarMATP1, matp1, -100, 100);
//Solution 0Variable
//0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3. 使用testSSvarMATP1解决MATP1问题
double[] tempvar = matp1.get(0).scaleVariables(testSSvarMATP1.get(0));
//0.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0
可以看出,我们翻车了!!!
因为在我们的预想中,使用同一个任务初始化的Solution使用同一个问题进行scale结果应该不变,但是这里编程了-100,这表明scaleVariables函数我们还有一些东西没有弄明白
for (int i = 0; i < numberOfVariables_; i++) {
double sl = decisionVariables[i].getLowerBound();
double su = decisionVariables[i].getUpperBound();
double pl = lowerLimit_[i];
double pu = upperLimit_[i];
// System.out.println("sl su pl pu" + sl+" "+ su+" "+ pl+" "+ pu);
//对于MATP3问题
// sl su pl pu0.0 1.0 0.0 1.0
// sl su pl pu0.0 1.0 -5.0 5.0
// sl su pl pu0.0 1.0 -5.0 5.0
// sl su pl pu0.0 1.0 -5.0 5.0
// sl su pl pu0.0 1.0 -5.0 5.0
// sl su pl pu0.0 1.0 -5.0 5.0
// sl su pl pu0.0 1.0 -5.0 5.0
// sl su pl pu0.0 1.0 -5.0 5.0
// sl su pl pu0.0 1.0 -5.0 5.0
// sl su pl pu0.0 1.0 -5.0 5.0
如上是MATP3中10个变量的范围,MATP3问题集变量范围
这表明下面两句话出了问题
double sl = decisionVariables[i].getLowerBound();
double su = decisionVariables[i].getUpperBound();
由于Variable类是Solution输出的因此查看Solution类,结果发现其并没有LowerLimit_和UpperLimit_属性
而调用的是ProblemSet对象的 UnifiedUpperLimit ()和 getUnifiedUpperLimit()方法,而我们知道ProblemSet对象的 UnifiedUpperLimit ()和 getUnifiedUpperLimit()是不针对单个Problem的,也就是不为了单独一个task而设置的,其统一的决策变量空间为[0,1],具体可以参考一下博文,而task即单个Problem的上下界可以通过 double pl = lowerLimit_[i];double pu = upperLimit_[i];
获得
- 在举个例子
testSSvarMATP1.get(0).getUnifiedLowerLimit();
testSSvarMATP1.get(0).getUnifiedUpperLimit();
//0
//1
这样就解释的通了,因为MMDTLZ中有一句
double vars[] = scaleVariables(solution);
而将所有问题的决策空间强行从1-0之间转换到Problem类定义的范围中
因此使用全0编码的MATP1初始化的1Solution,在MATP1和MATP3问题后缩放的结果是
printdoublearray
0.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0 -100.0
printdoublearray
0.0 -5.0 -5.0 -5.0 -5.0 -5.0 -5.0 -5.0 -5.0 -5.0
玩大一点,如果使用越界的解去缩放可以不?
例如一个第一个维度为0,其余维度为100的MATP1初始化的Solution
//测试迁移时的scaleVariables函数
double[] tempvar = matp1.get(0).scaleVariables(testSSvarMATP1.get(3));
//因为testSSvarMATP1本身就是使用MATP1问题集合初始化的,因此此处不会有变量范围的变化
tools.printdoublearray(tempvar);
//此时如果使用MATP3来对matp1做scale
tempvar = matp3.get(0).scaleVariables(testSSvarMATP1.get(3));
tools.printdoublearray(tempvar);
//Solution 3Variable
// 0.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0
printdoublearray
// 0.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0 19900.0
// printdoublearray
// 0.0 995.0 995.0 995.0 995.0 995.0 995.0 995.0 995.0 995.0