Matlab与Python实现排队竞争算法结果不一致问题求助
排队竞争算法跨语言实现结果差异问题排查
问题描述
- 分别基于Python、Matlab编写实现排队竞争算法(line-up competition algorithm),多次运行测试后发现:Matlab端计算结果更优,且输出为固定值;Python端计算结果不固定,精度表现始终不及Matlab端。
- 初期推测问题源于随机数生成逻辑或临界判定条件的差异,但对齐两端随机数规则与临界条件后,Python侧计算结果仍未达预期。
- 初始判断:编程语言仅会影响算法运行效率,不会改变算法本身的计算结果,因此附上两端完整实现代码,请求定位问题产生的具体原因。
两端实现代码
Python版本
from function_ca import function_ca import numpy as np upper_bound = np.array([6, 6]) lower_bound = np.array([0, 0]) r = 0.999 population = 10 npoint = 5 ul_bound = upper_bound - lower_bound x = np.zeros((npoint, 2)) ll = np.array([0, 0]) bb = np.array([0, 0]) xx = np.zeros((population, 2)) for i in range(2): cacu_1 = lower_bound[i] + ul_bound[i]*np.random.rand(npoint, 1) x[:, i] = cacu_1.reshape((npoint, )) y = function_ca(x) m = 1 while max(ul_bound) >= 0.0000001: y1 = np.sort(y) k = np.argsort(y) x_t = x.repeat(repeats=1, axis=1) for i in range(len(k)): x[i, :] = x_t[k[i], :] for i in range(npoint): for j in range(2): ll[j] = max(x[i, j] - ul_bound[j] * i / (2 * npoint), lower_bound[j]) bb[j] = min(x[i, j] + ul_bound[j] * i / (2 * npoint), upper_bound[j]) for ii in range(2): caculate_2 = ll[ii] + (bb[ii] - ll[ii]) * np.random.rand(population, 1) xx[:, ii] = caculate_2.reshape((population,)) yy = function_ca(xx) yy1 = np.sort(yy) kk = np.argsort(yy) if yy1[0] < y1[i]: x[i, :] = xx[kk[0], :] y1[i] = yy1[0] y = y1 m += 1 ul_bound = ul_bound * 0.99 print(m) print(x) print(y)
Matlab版本
clear close %bounds of varibles l=[0 0]; b=[6 6]; % l=[100 1000 1000 10 10 10 10 10]; % b=[10000 10000 10000 1000 1000 1000 1000 1000]; variable=size(l,2); %r=input('contraction factor 0.1-0.99:'); %npoint=input('population number:'); %reprod=input('production number:'); r=0.999; npoint=20; reprod=10; tim0=clock; dbl=b-l; for i=1:variable x(:,i)=l(i)+dbl(i)*rand(npoint,1); end y=funLCA(x); m=1; while max(dbl)>=0.000001%m<100% [y1,k]=sort(y); x=x(k,:); for i=1:npoint for j=1:variable ll(j)=max(x(i,j)-dbl(j)*i/(2*npoint),l(j)); bb(j)=min(x(i,j)+dbl(j)*i/(2*npoint),b(j)); end for ii=1:variable xx(:,ii)=ll(ii)+(bb(ii)-ll(ii))*rand(reprod,1); end yy=funLCA(xx); [yy1,kk]=sort(yy); if yy1(1)<y1(i) x(i,:)=xx(kk(1),:); y1(i)=yy1(1); end end y=y1; m=m+1; dbl=r*dbl; end time=etime(clock,tim0) m y=funLCA(x) x
问题根因
两端结果差异和编程语言本身无关,完全是代码实现层面的参数、逻辑不对齐导致的,核心问题如下:
- 核心算法参数未对齐
- 初始种群规模
npoint:Python端设置为5,Matlab端设置为20,4倍的种群规模差距直接决定算法全局搜索覆盖能力,Matlab端更大的种群规模自然更容易搜索到全局最优解 - 搜索域收缩系数:Python端虽然定义了
r=0.999,但迭代更新时硬编码为ul_bound = ul_bound * 0.99,完全没有使用定义的r参数;Matlab端则正确使用r=0.999做收缩,Python端搜索域收缩速度是Matlab的10倍,会快速缩小搜索范围,极易陷入局部最优,没有足够时间完成全局搜索 - 迭代终止阈值:Python端终止条件为搜索域最大值
>=1e-7,Matlab端为>=1e-6,阈值差一个数量级,两端迭代次数本身就不相同
- 初始种群规模
- 随机数种子未固定
Python端没有为numpy随机数生成器设置固定种子,每次运行的初始种群、随机采样点都不同,自然输出结果不固定;旧版本Matlab启动时会默认给随机数生成器设置固定初始种子,因此每次运行结果一致。 - 最终结果校验逻辑差异
Matlab端迭代结束后会重新调用目标函数funLCA(x)计算一次最终种群的适应度再输出,Python端直接输出迭代过程中缓存的y值,没有做最终校验,可能存在迭代过程中x、y更新不同步带来的误差。 - 冗余代码带来的潜在风险
Python端对种群排序重排时,额外做了一次无意义的x.repeat(repeats=1, axis=1)数组复制操作,虽然当前逻辑下不会出错,但属于冗余代码,存在索引错位的潜在风险,完全可以直接用x = x[k]实现和Matlab一致的排序重排逻辑。
内容的提问来源于stack exchange,提问作者max yin
相关产品推荐
相关产品推荐

