Microsoft Solver Foundation无法解决Excel解算器解决的问题

时间:2014-01-29 11:59:49

标签: c# excel ms-solver-foundation

我有约束的非线性优化问题。我用Excel Solver(GRG)解决了这个问题 但当我尝试使用Microsoft Solver Foundation将其翻译为C#时,它会获得solution.Quality = SolverQuality.Unknown

问题在于:我有一些决定并限制每一个的约束(上限和下限)。还有另外两个约束(这些是有问题的约束):

  • 决定的总和需要为1(100%)
  • (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;
}

有人有解决方案吗?

0 个答案:

没有答案