geatpy icon indicating copy to clipboard operation
geatpy copied to clipboard

小规模0-1规划找不到可行解

Open easyzhou2023 opened this issue 1 year ago • 4 comments

使用geatpy求解一个小规模0-1规划模型时,始终找不到可行解,已尝试过调参、更换算子、更换算法模板、放松等式约束。谢谢~ p.s 因规模很小,用cbc求解器求解可以快速找到最优解。 p.s 也尝试过传入先验知识(一个较差的可行解),有可行解,但可行解和最优解就是先验知识传入的解,即解没有任何改进。 数据middle_nonlinear.csv 代码如下;

# -*- coding: utf-8 -*-
import numpy as np
import geatpy as ea

class BOO(ea.Problem):
    def __init__(self, testName, M=2):  # testName:数据文件名; M : 目标维数
        name = testName
        self.data_d_ij = np.loadtxt(testName + ".csv", delimiter=",", usecols=np.arange(0,18))
        print(self.data_d_ij.shape)
        self.M = M
        maxormins = [1] * M
        Dim = self.data_d_ij.size      #变量个数
        print(Dim)
        varTypes = [1] * Dim     # 1: 离散
        lb = [0] * Dim
        ub = [1] * Dim
        lbin = [1] * Dim
        ubin = [1] * Dim
        ea.Problem.__init__(self,name,M,maxormins,Dim,varTypes,lb,ub,lbin,ubin)
        
    def evalVars(self, pop):
        # pop:种群染色体矩阵
        #Vars = pop.Phen     #Vars: 决策变量矩阵
        #Vars = pop.astype(int)   #强制类型转换确保元素是整数
        Vars = pop
        d_ij = self.data_d_ij.flatten(order='C')   #按行将矩阵data_d_ij 转换成一维数组 d_ij
        
        '''目标函数'''
        f1 = np.sum(d_ij*Vars, axis=1).reshape(-1,1)
        if self.M == 1:
            ObjV = f1
        else:
            f2 = -np.sum(d_ij*Vars, axis=1).reshape(-1,1)
            ObjV = np.hstack([f1, f2])
        
        '''约束'''
        num_i = self.data_d_ij.shape[0]    # num_row
        num_j = self.data_d_ij.shape[1]    # num_col
        eps = 1e-3    #放松等式约束
        for i in range(0, num_i):
            if i == 0:
                CV = np.abs(np.sum(Vars[:, i*num_j:(i+1)*num_j], axis=1) - 1.0).reshape(-1,1) - eps
            else:
                g1 = np.abs(np.sum(Vars[:, i*num_j:(i+1)*num_j], axis=1) - 1.0).reshape(-1,1) - eps
                CV = np.append(CV, g1, axis=1)
        for j in range(0, num_j):
            g2 = np.abs(np.sum(Vars[:,j::num_j], axis=1) - 1.0).reshape(-1,1) - eps
            CV = np.append(CV, g2, axis=1)
        for k in range(0, self.Dim):
            g3 = 0 - d_ij[k] * Vars[:,[k]]
            CV = np.append(CV, g3, axis=1)
        return ObjV, CV
M = 1
problem = BOO('middle_nonlinear', M)
algorithm = ea.soea_SGA_templet(
        problem,
        ea.Population(Encoding='RI', NIND=500),
        #prophetPop = pro_pop,   #传入先验知识
        MAXGEN=10000,  # 最大进化代数
        logTras=1)  # 表示每隔多少代记录一次日志信息,0表示不记录。
# 选择
#algorithm.selFunc = 'etour'
# 重组/交叉
algorithm.recOper = ea.Xovud()
algorithm.recOper.XOVR = 0.8  # 交叉概率
# 变异
algorithm.mutOper = ea.Mutuni()
algorithm.mutOper.Pm = 0.2   #变异概率
saveDirName = 'Xovud_Mutuni_result_'+str(M)
res = ea.optimize(algorithm,
                  verbose=True,
                  drawing=1,
                  outputMsg=True,
                  drawLog=False,
                  saveFlag=True,
                  dirName=saveDirName)

数学模型: checking

easyzhou2023 avatar Feb 23 '23 06:02 easyzhou2023