問題
線形計画法 (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
}
}
}
}