我有约束的非线性优化问题。我用Excel Solver(GRG)解决了这个问题
但当我尝试使用Microsoft Solver Foundation
将其翻译为C#时,它会获得solution.Quality = SolverQuality.Unknown
。
问题在于:我有一些决定并限制每一个的约束(上限和下限)。还有另外两个约束(这些是有问题的约束):
(MMULT(TRANSPOSE(Decision-Array),MMULT(Tabel-with-values,Decision-Array)))^0.5
需要等于另一个值目标是sum(Decision * value)
。我是这样写的Microsoft Solver Foundation:
SolverContext solverData = SolverContext.GetContext();
context.ClearModel();
model = context.CreateModel();
for (i=0 ; i< decisionCount; i++)
{
var decision = new Decision(SolverDomain.RealNonnegative, "decisions_" + i);
model.AddDecision(decision);
model.AddConstraint("limits_of_" + i, downConstraint(i) <= decision <= upConstraint(i));
}
var fdecision = new Decision(SolverDomain.RealNonnegative, "formula");
//mymatrix is double[,]
model.AddConstraint("f_constraint_1", fdecision == matMult(transpose(model.Decisions.ToList()),
matMult(matrix(mymatrix), transpose(model.Decisions.ToList()))[0, 0]);
//myAalue is double = givvenValue^2
solverData.model.AddConstraint("f_constraint_2", fdecision == myAalue);
var udecision = new Decision(SolverDomain.RealNonnegative, "upto100");
model.AddConstraint("upto1_constraint_1", udecision == UpTo100Precent(model.Decisions.ToList()));
model.AddConstraint("upto1_constraint_2", udecision == 1);
solverData.model.AddGoal("goal", GoalKind.Maximize, CalcGoal(model.Decisions.ToList()));
model.AddDecision(udecision);
model.AddDecision(fdecision);
Solution solution = context.Solve(new HybridLocalSearchDirective() { TimeLimit = 60000 });
//add here I get solution.Quality == SolverQuality.Unknown
这些是我在上面的代码中使用的函数:
private Term[,] matrix(Double[,] m)
{
int rows = m.GetLength(0);
int cols = m.GetLength(1);
Term[,] r = new Term[rows, cols];
for (int row = 0; row < rows; row++)
for (int col = 0; col < cols; col++)
r[row, col] = m[row, col];
return r;
}
private Term[,] matMult(Term[,] a, Term[,] b)
{
int rows = a.GetLength(0);
int cols = b.GetLength(1);
Term[,] r = new Term[rows, cols];
for (int row = 0; row < rows; row++)
for (int col = 0; col < cols; col++)
{
r[row, col] = 0;
for (int k = 0; k < a.GetLength(1); k++)
{
r[row, col] += a[row, k] * b[k, col];
}
}
return r;
}
private Term[,] transpose(Term[,] m)
{
int rows = m.GetLength(0);
int cols = m.GetLength(1);
Term[,] r = new Term[cols, rows];
for (int row = 0; row < rows; row++)
for (int col = 0; col < cols; col++)
{
r[col, row] = m[row, col];
}
return r;
}
private Term UpTo100Precent(List<Decision> decisions)
{
Term to100 = 0;
foreach (var decision in decisions)
{
to100 += decision;
}
return to100;
}
private Term CalcGoal(List<Decision> decisions)
{
Term x = 0;
//A is double[]
for (i = 0; i < decisions.Count ; i++)
{
x += decisions[i] * A[1]
}
return x;
}
有人有解决方案吗?