You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ALGLIB线性规划(C#)中约束变量为整数?

解决整数线性规划约束问题

一、在ALGLIB中添加整数变量约束

ALGLIB的MINLP模块支持整数变量约束,你可以通过minlpsetintvar方法将每个变量标记为整数类型。修改你的代码,在初始化state后添加变量类型约束,同时修正原代码中al数组长度错误(约束矩阵a为7行,对应al需7个元素):

double[] c = new double[] { 1, 2, 3, 1, 2, 3 };
double[,] a = new double[,]
{
{ 1, 2, 3, 1, 2, 3 },
{ 1, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 1 }
};
double[] lowerBounds = new double[] { 1, 1, 1, 1, 1, 1 };
double[] upperBounds = new double[] { double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity };
double[] s = new double[] { 1, 1, 1, 1, 1, 1 };
double[] x;
double[] al = new double[] { 16, 1, 1, 1, 1, 1, 1 };
double[] au = new double[] { double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity };
alglib.minlpstate state;
alglib.minlpreport rep;
alglib.minlpcreate(6, out state);
alglib.minlpsetcost(state, c);
alglib.minlpsetbc(state, lowerBounds, upperBounds);
alglib.minlpsetlc2dense(state, a, al, au, 7);

// 标记所有6个变量为整数类型
for (int i = 0; i < 6; i++)
{
    alglib.minlpsetintvar(state, i);
}

alglib.minlpsetscale(state, s);
alglib.minlpoptimize(state);
alglib.minlpresults(state, out x, out rep);
System.Diagnostics.Debug.WriteLine("{0}", alglib.ap.format(x, 3));

二、替代方案:使用Google OR-Tools求解整数线性规划

如果ALGLIB的MINLP求解效果不佳,推荐使用Google OR-Tools,它对整数线性规划(ILP)支持更完善,且免费开源。

首先通过NuGet安装Google.OrTools包,然后使用以下代码实现你的问题:

using Google.OrTools.LinearSolver;

class Program
{
    static void Main()
    {
        // 创建整数规划求解器
        Solver solver = Solver.CreateSolver("SCIP");
        if (solver == null) return;

        // 定义整数变量,下界为1,无上界
        Variable A = solver.MakeIntVar(1.0, double.PositiveInfinity, "A");
        Variable B = solver.MakeIntVar(1.0, double.PositiveInfinity, "B");
        Variable C = solver.MakeIntVar(1.0, double.PositiveInfinity, "C");
        Variable D = solver.MakeIntVar(1.0, double.PositiveInfinity, "D");
        Variable E = solver.MakeIntVar(1.0, double.PositiveInfinity, "E");
        Variable F = solver.MakeIntVar(1.0, double.PositiveInfinity, "F");

        // 添加约束:A+2B+3C+E+2D+3F >=16
        Constraint constraint = solver.MakeConstraint(16.0, double.PositiveInfinity);
        constraint.SetCoefficient(A, 1);
        constraint.SetCoefficient(B, 2);
        constraint.SetCoefficient(C, 3);
        constraint.SetCoefficient(D, 2);
        constraint.SetCoefficient(E, 1);
        constraint.SetCoefficient(F, 3);

        // 定义目标函数:最小化 A+2B+3C+D+2E+3F
        Objective objective = solver.Objective();
        objective.SetCoefficient(A, 1);
        objective.SetCoefficient(B, 2);
        objective.SetCoefficient(C, 3);
        objective.SetCoefficient(D, 1);
        objective.SetCoefficient(E, 2);
        objective.SetCoefficient(F, 3);
        objective.SetMinimization();

        // 求解并输出结果
        Solver.ResultStatus resultStatus = solver.Solve();
        if (resultStatus == Solver.ResultStatus.OPTIMAL)
        {
            System.Diagnostics.Debug.WriteLine($"最优解:");
            System.Diagnostics.Debug.WriteLine($"A = {A.SolutionValue()}");
            System.Diagnostics.Debug.WriteLine($"B = {B.SolutionValue()}");
            System.Diagnostics.Debug.WriteLine($"C = {C.SolutionValue()}");
            System.Diagnostics.Debug.WriteLine($"D = {D.SolutionValue()}");
            System.Diagnostics.Debug.WriteLine($"E = {E.SolutionValue()}");
            System.Diagnostics.Debug.WriteLine($"F = {F.SolutionValue()}");
            System.Diagnostics.Debug.WriteLine($"目标函数值:{solver.Objective().Value()}");
            // 验证约束
            double sum = A.SolutionValue() + 2 * B.SolutionValue() + 3 * C.SolutionValue() + E.SolutionValue() + 2 * D.SolutionValue() + 3 * F.SolutionValue();
            System.Diagnostics.Debug.WriteLine($"约束值验证:{sum} >=16 → {sum >=16}");
        }
        else
        {
            System.Diagnostics.Debug.WriteLine("未找到合法最优解");
        }
    }
}

该代码会直接输出满足所有整数约束的最优解,无需手动取整,且保证约束条件成立。

为什么直接取整不可行?

连续线性规划的最优解是松弛了整数约束后的结果,直接取整可能破坏约束条件(如你示例中的情况),同时也不一定是整数规划的最优解。必须通过专门的整数规划求解算法(如分支定界、割平面法)来找到合法的整数解。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 22:39:57