0

問題

線形計画法 (LP) の問題を解決する必要がある C# プロジェクトがあります。私はMicrosoft.SolverFoundation.InteriorPointSolver https://docs.microsoft.com/en-us/previous-versions/visualstudio/ff525706(v=vs.93)を使用しています。時々間違った解決策を見つけるという問題に直面しました。できる限りサンプルを減らしました (以下のコードを参照)。最初のブロックでは、正しい解は y = 5 ですが、出力では -5 に非常に近い数値が得られました。ただし、非常によく似た 2 番目のブロックは正しく機能します。

技術的な詳細

IDE: VisualStudio 2019 コミュニティ
プロジェクト: C# コンソール アプリケーション .NET 5
Microsoft.SolverFoundation v3.1.0

仮説

問題はsolver.AddGoal、最初の 2 つのブロックの 2 つの違いのうちの 1 つであるため、最後のパラメーター (`bool 最小化) の間違った理解にあると考えました。ただし、ブロック III と IV は正しく機能します。だから私は理由を見つけることができません。ありがとう!

using Microsoft.SolverFoundation.Solvers;
using System;

namespace SolverFoundationTest
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                // I.
                // y -> max
                // x = 1
                // 5x - y >= 0
                var solver = new InteriorPointSolver();
                solver.AddVariable("y", out var y);
                solver.AddVariable("x", out var x);
                solver.AddRow("goal", out var g);
                solver.AddGoal(g, 0, false);
                solver.SetCoefficient(g, y, 1);
                solver.SetBounds(x, 1, 1);
                solver.AddRow("constraint", out var c);
                solver.SetLowerBound(c, 0);
                solver.SetCoefficient(c, x, 5);
                solver.SetCoefficient(c, y, -1);
                var solution = solver.Solve(new InteriorPointSolverParams());
                var score = (double)solution.GetValue(y);
                Console.WriteLine(score);
                // -5,000000000129852 WRONG!
            }
            {
                // II.
                // y -> min
                // x = 1
                // 5x - y <= 0
                var solver = new InteriorPointSolver();
                solver.AddVariable("y", out var y);
                solver.AddVariable("x", out var x);
                solver.AddRow("goal", out var g);
                solver.AddGoal(g, 0, true);
                solver.SetCoefficient(g, y, 1);
                solver.SetBounds(x, 1, 1);
                solver.AddRow("constraint", out var c);
                solver.SetUpperBound(c, 0);
                solver.SetCoefficient(c, x, 5);
                solver.SetCoefficient(c, y, -1);
                var solution = solver.Solve(new InteriorPointSolverParams());
                var score = (double)solution.GetValue(y);
                Console.WriteLine(score);
                // 5,000000000129852 correct
            }
            {
                // III.
                // y -> min
                // -2 <= y <= 3
                var solver = new InteriorPointSolver();
                solver.AddVariable("y", out var y);
                solver.SetBounds(y, -2, 3);
                solver.AddRow("goal", out var g);
                solver.AddGoal(g, 0, true);
                solver.SetCoefficient(g, y, 1);
                var solution = solver.Solve(new InteriorPointSolverParams());
                var score = (double)solution.GetValue(y);
                Console.WriteLine(score);
                // -2 correct
            }
            {
                // IV.
                // y -> max
                // -2 <= y <= 3
                var solver = new InteriorPointSolver();
                solver.AddVariable("y", out var y);
                solver.SetBounds(y, -2, 3);
                solver.AddRow("goal", out var g);
                solver.AddGoal(g, 0, false);
                solver.SetCoefficient(g, y, 1);
                var solution = solver.Solve(new InteriorPointSolverParams());
                var score = (double)solution.GetValue(y);
                Console.WriteLine(score);
                // 3 correct
            }
        }
    }
}
4

0 に答える 0