我正在尝试使用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
),但矩阵乘法并不是那么简单。
我可以创建一个执行乘法并返回 a 的函数double
,但AddGoal()
需要一个Term对象,而且我还必须对Decision
对象进行算术运算。
或者,我可以将这个乘法分解为一个巨大的string
表达式(我已经完成了),但如果我不必这样做,我会更喜欢。(这个字符串看起来像"d1 * 5 + d2 * 1 + d3 * 0 ..."
:)
有任何想法吗?谢谢。
PS:正确答案(根据Excel)是:
d1 = 0.503497
d2 = 0.216783
d3 = 0.27972
注意:解决方案必须具有可扩展性以具有n
“决策”数量