Closed RebelYoung closed 6 months ago
另外提一下,这个测试里,第一代Gen=0的时候数据是对的。
@geatpy-dev 我试了SEGA算法,结果也对不上了,这是怎么回事,,。?
单步调试即可
单步调试即可
@geatpy-dev 我调试过了,就是对不上啊,我给你源码,你试试?
我这边用demo代码测试并无问题。应该涉及你的具体业务代码,需要你单步调试解决。
我这边用demo代码测试并无问题。应该涉及你的具体业务代码,需要你单步调试解决。 @geatpy-dev 你有没有测试,在evalVars中写出Vars,ObjV,CV和Population.save()的csv比对,我现在测试一下demo/moea_demo2中的文件,在evalVars函数中加入np.savetxt进行校验
@geatpy-dev 我调试了一遍,代码如下:只增加了outFunc,和evalVars中的写出。
10个个体,5代。每代存于Gen{i}中,比对Population.save()和np.savetxt的结果。
除了第一代以外,仍然不同。
import numpy as np
import geatpy as ea
from pathlib import Path
class MyProblem(ea.Problem): # 继承Problem父类
def __init__(self, M=2):
name = 'MyProblem' # 初始化name(函数名称,可以随意设置)
Dim = 1 # 初始化Dim(决策变量维数)
maxormins = [1] * M # 初始化maxormins(目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标)
varTypes = [0] * Dim # 初始化varTypes(决策变量的类型,0:实数;1:整数)
lb = [-10] * Dim # 决策变量下界
ub = [10] * Dim # 决策变量上界
lbin = [1] * Dim # 决策变量下边界(0表示不包含该变量的下边界,1表示包含)
ubin = [1] * Dim # 决策变量上边界(0表示不包含该变量的上边界,1表示包含)
# 调用父类构造方法完成实例化
ea.Problem.__init__(self,
name,
M,
maxormins,
Dim,
varTypes,
lb,
ub,
lbin,
ubin)
self.currentGen=0
self.opt_path=None
def evalVars(self, Vars): # 目标函数
if not (self.opt_path/f'Gen{self.currentGen}').exists():
(self.opt_path/f'Gen{self.currentGen}').mkdir(parents=True)
with open(self.opt_path / f'Gen{self.currentGen}' / f'Gen{self.currentGen}_Vars.txt', 'w') as writer:
np.savetxt(writer, Vars, delimiter=',')
f1 = Vars**2
f2 = (Vars - 2)**2
# # 利用罚函数法处理约束条件
# exIdx = np.where(Vars**2 - 2.5 * Vars + 1.5 < 0)[0] # 获取不满足约束条件的个体在种群中的下标
# f1[exIdx] = f1[exIdx] + np.max(f1) - np.min(f1)
# f2[exIdx] = f2[exIdx] + np.max(f2) - np.min(f2)
# 利用可行性法则处理约束条件
CV = -Vars**2 + 2.5 * Vars - 1.5
ObjV = np.hstack([f1, f2])
with open(self.opt_path / f'Gen{self.currentGen}' / f'Gen{self.currentGen}_ObjV.txt', 'w') as writer:
np.savetxt(writer, ObjV, delimiter=',')
with open(self.opt_path / f'Gen{self.currentGen}' / f'Gen{self.currentGen}_CV.txt', 'w') as writer:
np.savetxt(writer, CV, delimiter=',')
self.currentGen+=1
return ObjV, CV
def call_back1(alg: ea.Algorithm, pop: ea.Population):
if (alg.cwd/f'Gen{alg.currentGen}').exists():
pop.save(str(alg.cwd/f'Gen{alg.currentGen}'))
# -*- coding: utf-8 -*-
"""该案例展示了一个带约束连续决策变量的最小化目标的双目标优化问题的求解。详见MyProblem.py."""
# from MyProblem import MyProblem # 导入自定义问题接口
# import geatpy as ea # import geatpy
if __name__ == '__main__':
# 实例化问题对象
problem = MyProblem()
problem.opt_path=Path.cwd()/'debug\debug_moea'
# 构建算法
algorithm = ea.moea_NSGA2_templet(
problem,
ea.Population(Encoding='RI', NIND=10),
MAXGEN=5, # 最大进化代数
outFunc=call_back1,
logTras=0) # 表示每隔多少代记录一次日志信息,0表示不记录。
algorithm.cwd=problem.opt_path
# 求解
res = ea.optimize(algorithm,
verbose=False,
drawing=1,
outputMsg=True,
drawLog=False,
saveFlag=False,)
print(res)
@geatpy-dev 我调试了一遍,代码如下:只增加了outFunc,和evalVars中的写出。 10个个体,5代。每代存于Gen{i}中,比对Population.save()和np.savetxt的结果。 除了第一代以外,仍然不同。
import numpy as np import geatpy as ea from pathlib import Path class MyProblem(ea.Problem): # 继承Problem父类 def __init__(self, M=2): name = 'MyProblem' # 初始化name(函数名称,可以随意设置) Dim = 1 # 初始化Dim(决策变量维数) maxormins = [1] * M # 初始化maxormins(目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标) varTypes = [0] * Dim # 初始化varTypes(决策变量的类型,0:实数;1:整数) lb = [-10] * Dim # 决策变量下界 ub = [10] * Dim # 决策变量上界 lbin = [1] * Dim # 决策变量下边界(0表示不包含该变量的下边界,1表示包含) ubin = [1] * Dim # 决策变量上边界(0表示不包含该变量的上边界,1表示包含) # 调用父类构造方法完成实例化 ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin) self.currentGen=0 self.opt_path=None def evalVars(self, Vars): # 目标函数 if not (self.opt_path/f'Gen{self.currentGen}').exists(): (self.opt_path/f'Gen{self.currentGen}').mkdir(parents=True) with open(self.opt_path / f'Gen{self.currentGen}' / f'Gen{self.currentGen}_Vars.txt', 'w') as writer: np.savetxt(writer, Vars, delimiter=',') f1 = Vars**2 f2 = (Vars - 2)**2 # # 利用罚函数法处理约束条件 # exIdx = np.where(Vars**2 - 2.5 * Vars + 1.5 < 0)[0] # 获取不满足约束条件的个体在种群中的下标 # f1[exIdx] = f1[exIdx] + np.max(f1) - np.min(f1) # f2[exIdx] = f2[exIdx] + np.max(f2) - np.min(f2) # 利用可行性法则处理约束条件 CV = -Vars**2 + 2.5 * Vars - 1.5 ObjV = np.hstack([f1, f2]) with open(self.opt_path / f'Gen{self.currentGen}' / f'Gen{self.currentGen}_ObjV.txt', 'w') as writer: np.savetxt(writer, ObjV, delimiter=',') with open(self.opt_path / f'Gen{self.currentGen}' / f'Gen{self.currentGen}_CV.txt', 'w') as writer: np.savetxt(writer, CV, delimiter=',') self.currentGen+=1 return ObjV, CV def call_back1(alg: ea.Algorithm, pop: ea.Population): if (alg.cwd/f'Gen{alg.currentGen}').exists(): pop.save(str(alg.cwd/f'Gen{alg.currentGen}')) # -*- coding: utf-8 -*- """该案例展示了一个带约束连续决策变量的最小化目标的双目标优化问题的求解。详见MyProblem.py.""" # from MyProblem import MyProblem # 导入自定义问题接口 # import geatpy as ea # import geatpy if __name__ == '__main__': # 实例化问题对象 problem = MyProblem() problem.opt_path=Path.cwd()/'debug\debug_moea' # 构建算法 algorithm = ea.moea_NSGA2_templet( problem, ea.Population(Encoding='RI', NIND=10), MAXGEN=5, # 最大进化代数 outFunc=call_back1, logTras=0) # 表示每隔多少代记录一次日志信息,0表示不记录。 algorithm.cwd=problem.opt_path # 求解 res = ea.optimize(algorithm, verbose=False, drawing=1, outputMsg=True, drawLog=False, saveFlag=False,) print(res)
@geatpy-dev 你直接运行试一下,比对f'Gen{i}/Gen{i}_ObjV.txt'
和f'Gen{i}/ObjV.csv'
代码其余部分没有动过,是demo/moea_demo2 @geatpy-dev
@geatpy-dev ,有没有测试一下
Geatpy内置并无call_back方法,你需要自己单步调试检查你的代码。
Describe the bug 回调函数中我使用了ea.Population.save()函数,存下这一代的信息和在self.evalVars()函数中直接文本写出Vars,ObjV,CV完全对不上。
To Reproduce Steps to reproduce the behavior:
以下是一个非常非常简单的测试problem,测试中,我用了Dim=2,NIND=10
我在evalVars函数中直接将Vars,ObjV,CV写入了文本。 RI编码下,Phen和写入Vars应该一致。。。结果完全对不上,而且NIND越大,偏差越大。。。有近似值,但是误差无法结束,且近似值的index也不对!
这个问题造成我中间文件留下的信息,和最后优化结果无法比对!!!
我在想这是不是nsga2的问题?父代子代合并?但是中间数据也存在对不上的问题。