Microsoft Solver Foundation doesn't solve what is solved by Excel solver

1k Views Asked by At

I have a non-linear optimization problem with constraints. I solved it with Excel Solver (GRG) but when I tried to translate it to C# with Microsoft Solver Foundation it gets solution.Quality = SolverQuality.Unknown.

The problem is this: I have some decisions and limit constraints (upper and lower) for every one of them. And two other constraints (this ones are the problematic constraints):

  • the sum of the Decision need to be 1 (100%)
  • (MMULT(TRANSPOSE(Decision-Array),MMULT(Tabel-with-values,Decision-Array)))^0.5 needs to be equal to another value

The goal is sum(Decision * value). I write it by Microsoft Solver Foundation like this:

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

These are the functions I use in above code:

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;
}

Does someone have a solution?

0

There are 0 best solutions below