You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Java中用Gurobi收集混合整数线性规划多解的技术求助

如何用Gurobi Java API获取多个混合整数线性规划解

嘿,作为Java新手能写到这一步已经很棒了!要获取多个解,核心是让Gurobi在求解时保留多个可行解,然后遍历所有可用解逐个提取。我帮你一步步修改代码:

关键改动点

  • 首先开启解池功能:在调用model.optimize()之前,设置PoolSolutions参数,告诉Gurobi最多保留多少个解(比如设为10,你可以根据需求调整)。
  • 遍历所有找到的解:Gurobi的解编号从0开始,到SolCount-1结束,每个编号对应一个可行解,逐个提取变量值。
  • 补全CLSPSolutionCollection的构造函数:你现在的构造函数里没初始化solutions列表,直接add会报空指针,得补上。

修改后的完整代码

优化器部分代码

CLSPSolutionCollection collection = new CLSPSolutionCollection();
try {
    // 关键:开启解池,设置最多保留10个解(可按需调整)
    model.set(GRB.IntParam.PoolSolutions, 10);
    model.optimize();

    // 检查是否找到可行解(不一定是最优,也可以考虑FEASIBLE状态)
    if (model.get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL || 
        model.get(GRB.IntAttr.Status) == GRB.Status.FEASIBLE) {
        
        int solutionCount = model.get(GRB.IntAttr.SolCount);
        System.out.println("找到 " + solutionCount + " 个可行解");

        // 遍历每个解,从0到solutionCount-1
        for (int solIdx = 0; solIdx < solutionCount; solIdx++) {
            CLSPSolution sol = new CLSPSolution(K, T);
            // 切换到当前解
            model.set(GRB.IntParam.SolutionNumber, solIdx);
            
            // 获取当前解的目标值
            sol.setObjectiveValue((int) model.get(GRB.DoubleAttr.ObjNVal));
            
            // 提取所有决策变量的值
            for (int k = 0; k < K; k++) {
                for (int t = 0; t < T; t++) {
                    sol.setProductionQuantity(k, t, q[k][t].get(GRB.DoubleAttr.Xn));
                    sol.setSetupDecision(k, t, gamma[k][t].get(GRB.DoubleAttr.Xn));
                    sol.setOvertimeDecision(t, beta[t].get(GRB.DoubleAttr.Xn));
                }
            }
            
            // 将当前解加入集合
            collection.add(sol);
        }
    }

    // 资源释放
    model.dispose();
    env.dispose();
} catch (GRBException e) {
    e.printStackTrace();
}
return collection;

补全CLSPSolutionCollection类

public class CLSPSolutionCollection {
    private ArrayList<CLSPSolution> solutions;

    // 补全构造函数,初始化列表
    public CLSPSolutionCollection() {
        solutions = new ArrayList<>();
    }

    public void add(CLSPSolution solution) {
        solutions.add(solution);
    }

    public int size() {
        return solutions.size();
    }

    public CLSPSolution get(int index) {
        return solutions.get(index);
    }
}

额外说明

  • 解池参数调整:除了PoolSolutions,还可以设置PoolSearchMode来控制Gurobi寻找多个解的策略(比如设为1会更积极地找不同的解),具体可以参考Gurobi官方文档。
  • 解的状态:如果问题没有最优解但有可行解,model.get(GRB.IntAttr.Status)会是GRB.Status.FEASIBLE,所以代码里加上这个判断能拿到更多可行解。
  • 变量提取注意:每个解都要新建CLSPSolution对象,不能复用同一个,否则会覆盖之前解的变量值。

内容的提问来源于stack exchange,提问作者Stijn

火山引擎 最新活动