1、问题1
参考博客:
https://blog.csdn.net/gzp444280620/article/details/49272977
https://blog.csdn.net/qq_27262673/article/details/79635924
https://blog.csdn.net/lanluyug/article/details/84100233
https://blog.csdn.net/fan_h_l/article/details/81981715
1、描述
在将mtalab语言的MO-MFEA-II算法改成python语言的过程中,遇到一个内置函数fminbnd
,我尝试使用scipy包下的minimize
优化包,对matlab中同样的函数进行了测试:
matlab对应的测试要求如下(fminbnd):
python代码如下:
from scipy.optimize import minimize
import numpy as np
def test_fun1(x):
return np.sin(x)
bnds = ((0, 6.28),)
x0 = np.array((0.1,))
x0_min = 0
mymin1 = minimize(test_fun1, x0=((x0,)), method='SLSQP', bounds=bnds)
print(mymin1)
测试结果:
fun: array([2.77555756e-17])
jac: array([1.])
message: 'Optimization terminated successfully'
nfev: 4
nit: 2
njev: 2
status: 0
success: True
x: array([2.77555756e-17])
得到的结果和matlab差距很大。
2、解决方法
通过查看关于scipy.optimize
的文档,发现是初始点x0
对于结果影响很大,因此,对定义域bounds
设置多个初始点找到最优值就可以解决。
from scipy.optimize import minimize
import numpy as np
def test_fun1(x):
return np.sin(x)
bnds = ((0, 6.28),)
x0 = np.array((0.1,))
min = 0
x0_min = 0
for x0 in np.linspace(0, 2 * np.pi, 100):
mymin1 = minimize(test_fun1, x0=((x0,)), method='SLSQP', bounds=bnds)
if mymin1.fun < min:
min = mymin1.fun
x0_min = mymin1.x
print(mymin1)
测试结果:
fun: array([-0.68277266])
jac: array([0.00018513])
message: 'Optimization terminated successfully'
nfev: 20
nit: 8
njev: 8
status: 0
success: True
x: array([2.0061333])
2、问题2
在解决问题1的基础上,编写LearnRMP.py
类的过程中还是发现得到的结果rmpMatrix
和matlab中的相差很大,并且全部集中在0
点。
python代码:
import copy
from scipy.optimize import minimize as somin
bnds = ((0, 1),)
min = 0
x0_min = 0
for x0 in np.linspace(0, 1, 100):
mymin1 = somin(self.fun_rmp, x0=((x0,)), args=(prob_matrix, num_tasks), method='SLSQP', bounds=bnds)
if mymin1.fun < min:
min = mymin1.fun
x0_min = mymin1.x
def fun_rmp(self, rmp, prob_matrix, num_tasks):
# rmp是一个待求解的未知数
#
temp = copy.deepcopy(prob_matrix)
# print(temp is prob_matrix)
# 需要保证下次再进来时,prob_matrix重新计算
f = 0
# 只针对两个task的情况
for i in range(2):
for j in range(2):
if i == j:
temp[i][:, j] = temp[i][:, j] * (1 - (0.5 * (num_tasks - 1) * rmp / num_tasks))
else:
temp[i][:, j] = temp[i][:, j] * 0.5 * (num_tasks - 1) * rmp / num_tasks
f = f + np.sum(-np.log(np.sum(temp[i], axis=1)))
return f
matlab代码:
function f = loglik(rmp,popdata1,ntasks)
load popdatas
popdata2 = popdata; % 加载的测试数据popdata.mat
f = 0;
% 只针对两个task的情况
for i = 1:2
for j = 1:2
if i == j
popdata2(i).probmatrix(:,j) = popdata2(i).probmatrix(:,j)*(1-(0.5*(ntasks-1)*rmp/ntasks));
else
popdata2(i).probmatrix(:,j) = popdata2(i).probmatrix(:,j)*0.5*(ntasks-1)*rmp/ntasks;
end
end
% log(sum(popdata(i).probmatrix,2))对应的是还没有求和,应该是51 *1 维度的数据
% 结果是一个数值:47.816808059834540
f = f + sum(-log(sum(popdata2(i).probmatrix,2)));
end
end
popdata.mat数据集链接popdata.mat。
temp = copy.deepcopy(prob_matrix)
使用深拷贝,否则,在somin
再次进入到循环中时,会使用改变prob_matrix
值进行计算,但是,我们需要保证prob_matrix
相同才具备可比性。
python代码测试时prob_matrix
对应的数据如下,和popdata.mat
数据等同:
prob_matrix = []
prob_matrix1 = np.array([[1.11716844129861,
4.71393657106323,
2.55168796877439,
3.94095950485577,
0.100464746325594,
3.53869389479123,
1.29521721743105,
2.66394933885319,
3.53869389479123,
0.777249513019518,
3.53869389479123,
2.66394933885319,
1.92835947726621,
2.55168796877439,
3.36667190165201,
0.955609682731617,
4.71393657106323,
0.888760308532650,
1.29217023815337,
0.888760308532650,
2.88741785118975,
0.858441642902640,
1.86987090166128,
0.955609682731617,
4.50153438865269,
0.926467076944258,
1.14091564052811,
1.14091564052811,
1.14091564052811,
2.22076008553687,
4.54407070020539,
3.94095950485577,
0.116781950031863,
5.59570095873741,
1.06493277694369,
0.926467076944258,
1.92835947726621,
1.26685011350135,
2.45155663351179,
0.768723050307381,
4.29859343973936,
2.45155663351179,
0.0678624756316267,
2.55168796877439,
3.53869389479123,
4.54407070020539,
0.100464746325594,
4.29859343973936,
1.24043512545008,
2.45155663351179,
1.29521721743105,
4.54407070020539,
3.53869389479123,
0.858441642902640,
5.59570095873741,
1.86987090166128,
4.54407070020539,
1.14091564052811], [6.69974493314337e-09,
0.00871031700606005,
0.0101730020464706,
1.19255925024188e-05,
8.41182246795239e-07,
8.64100622529767e-06,
5.49380171110760e-07,
0.00881117454998680,
8.64100622529767e-06,
9.75986044218065e-08,
8.64100622529767e-06,
0.00881117454998680,
1.91024131451198e-07,
0.0101730020464706,
0.00235885477741280,
42.7376025012685,
0.00871031700606005,
1.75709333942571e-08,
25.1236323121315,
1.75709333942571e-08,
1.83771335770909e-06,
4.95694860160514e-09,
1.73913465113332e-07,
42.7376025012685,
1.66408718894915e-05,
2.75145527307760e-08,
1.72942921539587e-07,
1.72942921539587e-07,
1.72942921539587e-07,
0.0131631403168415,
0.420801791874576,
1.19255925024188e-05,
8.73183909474761e-07,
0.0136977687375853,
1.68105681649970e-07,
2.75145527307760e-08,
1.91024131451198e-07,
3.72567439305931e-07,
0.0118197596164081,
5.33728596906524e-09,
0.00617201738766273,
0.0118197596164081,
1.51020682736978e-07,
0.0101730020464706,
8.64100622529767e-06,
0.420801791874576,
8.41182246795239e-07,
0.00617201738766273,
0.0214088272597854,
0.0118197596164081,
5.49380171110760e-07,
0.420801791874576,
8.64100622529767e-06,
4.95694860160514e-09,
0.0136977687375853,
1.73913465113332e-07,
0.420801791874576,
1.72942921539587e-07]])
prob_matrix2 = np.array([[0.0499979221000443,
0.0561533978485839,
0.0817204548789998,
0.311819743072892,
2.26958566860012,
0.0660687997747887,
0.765051363262201,
0.311819743072892,
1.10249008713518,
2.58785042912107,
0.0533336492751069,
0.158752639426855,
0.0980872807934810,
0.170432201050043,
0.197349509952515,
0.0817204548789998,
0.0817204548789998,
0.102361142618165,
0.211696303219118,
0.227978333808826,
0.0980872807934810,
0.249951934917041,
1.84671063668057,
2.58785042912107,
0.378716438292197,
0.101529617668846,
0.170432201050043,
0.377481222424176,
0.0980872807934810,
0.197349509952515,
0.158752639426855,
1.27362255968794,
0.765051363262201,
0.378716438292197,
0.311819743072892,
0.249951934917041,
0.227978333808826,
0.203602075923167,
0.311819743072892,
0.170432201050043,
0.175361754235257,
1.79567009875754], [2597.52984696190,
2536.21410059152,
2517.40393309764,
2894.80235696776,
0.217302516485449,
2755.54298920314,
0.00368845453414693,
2894.80235696776,
0.00531921499673108,
0.441563787967357,
2509.44214272543,
2346.75601037283,
2295.12765551390,
3699.41383781112,
3760.23025252735,
2517.40393309764,
2517.40393309764,
3491.08472091405,
3921.49575230718,
4107.56790530165,
2295.12765551390,
3789.19465152841,
0.0104114297174405,
0.441563787967357,
4466.71881268681,
2764.62977177189,
3699.41383781112,
3035.08325434452,
2295.12765551390,
3760.23025252735,
2346.75601037283,
6134.90486825755,
0.00368845453414693,
4466.71881268681,
2894.80235696776,
3789.19465152841,
4107.56790530165,
2634.22150404028,
2894.80235696776,
3699.41383781112,
2430.91558384157,
0.168472803579713]])
prob_matrix.append(prob_matrix1.transpose())
prob_matrix.append(prob_matrix2.transpose())
经过测试,python和matlab代码找到的rmp
在0.3026
左右。