gurobi学习笔记1OR-Tools约束规划(2)输出所有可行解

列出多个可行解
方法为定义一个回调接口供Solver使用,方便获取所有的解

# 定义一个类VarArraySolutionPrinter(大意为多可行解,官网命名), 类中命名方法:cp_model.CpSolverSolutionCallback
class VarArraySolutionPrinter(cp_model.CpSolverSolutionCallback):

python使用类(class)来创建对象
class 类名(父类名:成员函数及成员变量),其中父类名可略,默认为object
父类名表示继承这个父类的属性

    #定义函数:命名为self,有variables属性   
    def __init__(self, variables): 

__init__表示类的对象被建立时,马上运行,对对象进行初始化。
在对类对象(class)进行实例化过程中,为防止缺少类中属性等情况发展,希望将类“封装”,解决方法为类内部定义一个def __init__(命名, 属性1,属性2)函数,在执行实例化过程中预先设定好需要哪些属性,同时可以在输入class中不同实例时可以正确地初始化
相当于用先用一段注释占着__init__函数内的位置
定义__init__后,执行实例化的过程须变成命名(属性1, 属性2) 新建的实例包括其参数,传给__init__函数并初始化后,执行它。
def __init__(命名, 属性1,属性2)语句中习惯上J将命名设为self。新建的实例传给self后,就可以在__init__函数内创建并初始化它的属性,一般呈现为 def __init__(self, 属性1,属性2)

    cp_model.CpSolverSolutionCallback.__init__(self)#调用__init__(self)
    self.__variables = variables   #定义selfvariables等于求到的解
    self.__solution_count = 1     #定义solution_count等于1,用于计数结构数

__前单下划线:保护变量,一般只能够被类对象和子类对象内部才能够访问到这些变量,一般情况下外部不得访问,

 def on_solution_callback(self):
        print('可行解第 %i 组' % self.__solution_count)
        print('目标函数值 = %i' % self.ObjectiveValue())
        for v in self.__variables: #遍历self.__variables
            print('  %s = %i' % (v, self.Value(v)), end=' ')#end=' '不换行
        print()  #输出空一行
        self.__solution_count += 1 #解的组数加1
def solution_count(self):#定义函数colution_count,用于组数
    return self.__solution_count

return 返回值的重要性 定义了一个函数,建议都带一个返回值,不然无法进行赋值

#完整代码
#导入OR-Tools中的CP-SAT求解器中的cp_model模块
from ortools.sat.python import cp_model
# 定义一个回调接口供Solver使用,方便获取所有的解

# 定义一个类VarArraySolutionPrinter( 多可行解), 类中调用方法:cp_model.CpSolverSolutionCallback
class VarArraySolutionPrinter(cp_model.CpSolverSolutionCallback):
    def __init__(self, variables):#定义函数。命名为self,包含variables变量
        cp_model.CpSolverSolutionCallback.__init__(self)
        self.__variables = variables #定义self.__variables等于变量
        self.__solution_count = 0#从1开始计数

    def on_solution_callback(self):#定义函数callback,用于输出结果
        print('可行解第 %i组' % self.__solution_count)
        print('目标函数值 = %i' % self.ObjectiveValue())
        for v in self.__variables:#遍历self.__variables,为输出变量各值
            print('  %s = %i' % (v, self.Value(v)), end=' ')#end=' '表示不换行
            print() #换行
        self.__solution_count += 1

    def solution_count(self):#定义函数colution_count,用于组数
        return self.__solution_count  #返回解的组数值

    #以上官方文件略修改
def main():

    # 实例化CP约束规划模型类
    model = cp_model.CpModel()

    # 创建变量,和线性规划一样,需要指定变量的取值范围
    x1 = model.NewIntVar(0, 4, 'x1')  
    x2 = model.NewIntVar(0, 3, 'x2')

    # 添加约束
    model.Add(x1+ 3*x2 <=8)

    # 添加目标函数
    model.Maximize(2*x1 + 3* x2)

    # 创建求解器并求解
    solver = cp_model.CpSolver() #使用CpSolver求解
    solution_printer = VarArraySolutionPrinter([x1, x2]) #按照前面 VarArraySolutionPrinter函数,打印出x1, x2,此时[x1, x2]已经赋值给了ariables
    status = solver.SolveWithSolutionCallback(model, solution_printer)

    # 打印结果
    print('求解状态 = %s' % solver.StatusName(status))
#注意到的,在后面有一行是打印求解状态的solver.StatusName(status),关于求解器的结果有这么几种:
# OPTIMAL:找到了最优可行解
# FEASIBLE:找到了一个可行的解,但我们不知道它是否是最优解
# INFEASIBLE:这个问题被证明是不可行的
# MODEL_INVALID:给定的CpModelProto没有通过验证步骤,建议可以通过调用ValidateCpModel(model_proto)来获得详细的错误信息
# UNKNOWN:模型的状态是未知的,因为已经达到了搜索限制
    print('可行解数量: %i' % solution_printer.solution_count())


main()
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值