2

我有一个带有约束的非线性优化问题。我用 Excel Solver (GRG) 解决了它,但是当我尝试将它翻译成 C# 时,Microsoft Solver Foundation它得到了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;
}

有人有解决方案吗?

4

0 回答 0