Microsoft Solver Foundationを使用して、行列の乗算に関する問題を最適化しようとしています。Excel のソルバーを使用してこれを行うことができますが、C# に統合しようとしていて問題が発生しています。以下に例を挙げて説明します。
次のように定義された (3x3) 行列yがあるとします。
Double[][] y =
{
new Double[] { 5, 1, 0 },
new Double[] { 1, 9, 1 },
new Double[] { 0, 1, 9 },
};
最小化されるような(1x3) 行列xを見つけたいです。x * y * x'
さらに、x値の合計が 1 になる必要があり、どの x値も 0 未満であってはなりません。
これが私がこれまでに持っているコードです:
SolverContext context = SolverContext.GetContext(); // Get context environment
Model model = context.CreateModel(); // Create a new model
Decision d1 = new Decision(Domain.RealNonnegative, "d1"); // First item in "x" vector (must be >= 0)
Decision d2 = new Decision(Domain.RealNonnegative, "d2"); // Second item in "x" vector (must be >= 0)
Decision d3 = new Decision(Domain.RealNonnegative, "d3"); // Third item in "x" vector (must be >= 0)
model.AddDecisions(d1, d2, d3); // Add these to the model (this is where the outputs will be stored)
model.AddConstraints("limits", // Add constraints
0 <= d1 <= 1, // Each item must be between 0 and 1
0 <= d2 <= 1,
0 <= d3 <= 1,
d1 + d2 + d3 == 1); // All items must add up to 1
私が立ち往生している部分は、最小化したいものを伝えるときです。
model.AddGoal("min", GoalKind.Minimize, /* What goes here? */);
通常、この部分には方程式 ( などd1 * d2 + d3
) が含まれますが、行列の乗算はそれほど単純ではありません。
乗算を実行して を返す関数を作成できますがdouble
、AddGoal()
Termオブジェクトが必要であり、オブジェクトに対して算術演算を行う必要がありDecision
ます。
別の方法として、この乗算を大きなstring
式に分解することもできますが (これは既に行っています)、この方法で行う必要がない方がよいと思います。(この文字列は次のようになります"d1 * 5 + d2 * 1 + d3 * 0 ..."
:)
何か案は?ありがとう。
PS: 正解 (Excel による) は次のとおりです。
d1 = 0.503497
d2 = 0.216783
d3 = 0.27972
n
注: ソリューションは、多数の「決定」を行うためにスケーラブルである必要があります。