划分问题的整数规划求解-cplex

该博客介绍了如何利用Java和Cplex的建模工具Leapms来解决整数规划问题。数据参数定义了一个整数集合,目标是找到一个划分,使两个子集的整数和相等。通过建立IloCplex模型,定义变量并设置目标函数与约束,最终求解并输出了结果。
摘要由CSDN通过智能技术生成

问题介绍

给定一个大小不等的整数集合,问是否可以把这些整数划分成两个集合,任何一个整数或者在集合S1中或者在S2中,但不能同时在两个集合中;对任意给的一个整数集合,请设计算法,解决是否存在一个划分,使得S1种整数之和恰好等于S2集合的整数之和。

数学模型

在这里插入图片描述

leapms介绍

使用Java+cplex求解问题前,先介绍一种全新且高效的建模工具——Leapms。
Leapms 是一个用于求解整数规划的免费建模语言,具备简洁的建模过程。Leapms 语言设计的原则包括:(1)采用描述性语言形式;(2)尽力与模型的数学表达形式一致。leapms软件应用网站:https://www.cnblogs.com/leapms/
语言开发者:陆教授(yplu@bjtu.edu.cn)

数据定义

//    数据参数定义
class DataParition{
    //        整数集合
    double[] partSet={11,47,159,137,85,47,142,35,119,61,88,175,13,96,-11,176,126,15,98,46,163};
    //        数量
    int setNumber=partSet.length;
}

问题建模

public class PartitionDemo {
    //    定义数据
    DataParition data;
    public PartitionDemo(DataParition data){
        this.data=data;
    }
    //    定义cplex内部对象
    IloCplex model;
    //    定义变量
    public IloNumVar[] x;
    public IloNumVar[] d;

    //    求解函数
    public void solve() throws IloException {
        if(model.solve()==false){
//            模型不可解
            System.out.println("模型不可解");
            return;
        }
        else{
            System.out.println("目标值:"+model.getObjValue());
            System.out.println("=========集合1===========");
            double num1=0;
            for(int i=0;i<data.setNumber;i++){
                if(model.getValue(x[i])!=0) {
                    num1+=data.partSet[i];
                    System.out.print(data.partSet[i]+"\t");
                }
            }
            System.out.print("\n 集合1元素之和为:"+num1);
            System.out.println();
            System.out.println("=========集合2===========");
            double num2=0;
            for(int i=0;i<data.setNumber;i++){
                if(model.getValue(x[i])==0) {
                    num2+=data.partSet[i];
                    System.out.print(data.partSet[i]+"\t");
                }
            }
            System.out.print("\n 集合2元素之和为:"+num2);
        }
    }

    //    根据数学模型建立求解模型
    public void BuildModel() throws IloException{
//        model
        model = new IloCplex();
        model.setOut(null);
//        variables
        x = new IloNumVar[data.setNumber];
        d = new IloNumVar[1];
//        定义cplex变量x和d的数据类型及取值范围
        for(int i=0;i<data.setNumber;i++){
            x[i]=model.numVar(0,1, IloNumVarType.Int,"x["+i+"]");
        }
        for(int i=0;i<1;i++) {
            d[i] = model.numVar(0, 1e15, IloNumVarType.Float, "d["+i+"]");
        }
//        设置目标函数
        model.addMinimize(d[0]);
//        集合元素之和计算
        IloNumExpr expr01 = model.numExpr();
        IloNumExpr expr02 = model.numExpr();
        for(int i=0;i<data.setNumber;i++){
            expr01=model.sum(expr01,model.prod(x[i],data.partSet[i]));
            expr02=model.sum(expr02,model.prod(data.partSet[i],model.sum(1,model.prod(-1,x[i]))));
        }
//        添加约束1
        IloNumExpr expr1 = model.numExpr();
        expr1=model.sum(expr01,model.prod(-1,expr02));
        model.addGe(d[0],expr1);

//        添加约束2
        IloNumExpr expr2 = model.numExpr();
        expr2=model.sum(expr02,model.prod(-1,expr01));
        model.addGe(d[0],expr2);

    }

问题求解

public static void main(String[] args)throws IloException{
        DataParition data =new DataParition();
        PartitionDemo lp=new PartitionDemo(data);
        lp.BuildModel();
        lp.solve();
    }

求解结果

在这里插入图片描述

=======================================
今天到此为止,后续记录其他cplex技术的学习过程。
以上学习笔记,如有侵犯,请立即联系并删除!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南音小榭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值