1

I'm starting to use Solver Foundation in a WPF/C# app, which should replace an Excel sheet that solves a linear problem, something simple like this:

  • Mix A: (20% A + 70% B + 10% C)
  • Mix B: (35% A + 65% C)
  • Mix C: (10% A + 80% B + 10% D)

How much do I need of each mix to get as closest as possible to (15% A + 70% B + 10% C + 5% D).

Pretty simple, even for Excel. So... I create this model in an OML string, and solve it with Solver Foundation, but the results are not the same as I get in Excel, and in every case the quadratic error I get is bigger with the Solver Foundation results (checked in the Excel sheet).

Is there any way I can configure the solver to get the same result as in Excel? If you need to see the OML, please ask and I'll update the question.

Guvante
  • 18,775
  • 1
  • 33
  • 64
Hannish
  • 1,482
  • 1
  • 21
  • 33
  • Are you sure you are attempting to minimize the same result? Maybe the two methods are using a different difference measurement. – Guvante Jan 04 '13 at 19:55
  • @Guvante thank you for your interest. I'll double check if I am using the same difference measurement, although I'm new to OML and maybe I am missing something. – Hannish Jan 04 '13 at 20:23
  • @Guvante I think you are right, I found a slight difference in the two difference measurements, I modified it but still the problem persists, although now the results obtained may be similar enough to keep it this way. Please post your comment as an answer for me to approve it, thanks. – Hannish Jan 05 '13 at 10:51

2 Answers2

1

I have tried your problem. As show below, MSF resulted in a similar if not smaller residual error.

My C# code for Microsoft Solver Foundation:

using System;
using Microsoft.SolverFoundation.Services;

namespace akMSFStackOverflow
{
    class Program
    {
        static void Main(string[] args)
        {
            SolverContext context = SolverContext.GetContext();             

            Decision a = new Decision(Domain.RealNonnegative, "A");
            Decision b = new Decision(Domain.RealNonnegative, "B");

            Model model = context.CreateModel();
            model.AddDecisions(a, b);

            Term c = 1.0 - a - b;                      //  a + b + c sum up to 100%
            Term errA = (a * 0.20 + b * 0.35 + c * 0.10) - 0.15;  //  resulting percentage of A should be 15%
            Term errB = (a * 0.70 + c * 0.80) - 0.70;
            Term errC = (a * 0.10 + b * 0.65) - 0.10;
            Term errD = (c * 0.10)            - 0.05;
            Term goal = errA * errA + errB * errB + errC * errC + errD * errD;

            //  ingredients sum up to 100% of the required volume
            //  constraint is not necessary as c is defined to be 1 - a - b
            model.AddConstraints("total", 1.0 == a + b + c);

            model.AddGoal("goal", GoalKind.Minimize, goal);

            // could specify the IPM solver, as we have a quadratic goal 
            Solution solution = context.Solve();

            Report report = solution.GetReport();
            Console.WriteLine("a={0} b={1}", a, b);
            Console.Write("{0}", report);
        }
}
}

The results:

goal: 0,000173076935386814

A: 0,369230770226158
B: 0,0846153845073738

Excel 2010 solver came up with:

goal: 0.00017308

A: 0.36923685
B: 0.08461443
Axel Kemper
  • 10,544
  • 2
  • 31
  • 54
  • You can simply define an array of Decisions and pass it to the solver model. AddDecisions() also accepts an array. The same holds for the error Terms and the goal calculation. – Axel Kemper Jan 06 '13 at 19:49
  • Just to make sure... is there a typo in this line: Term errA = (a * 0.20 + b * 0.35) - 0.15;. Shouldn't it be Term errA = (a * 0.20 + b * 0.35 + c * 0.10) - 0.15;? Thank you for letting me know that you can pass an array – Hannish Jan 06 '13 at 19:51
  • Yes, you are right. I corrected the error in my solution. The residual error is now a bit smaller. MSF is still a (rounding?) nuance better than Excel. – Axel Kemper Jan 06 '13 at 20:52
  • I agree with you, the difference is most probably because of rounding. – Hannish Jan 06 '13 at 22:20
1

Are you sure you are attempting to minimize the same result?

Maybe the two methods are using a different difference measurement.

For instance you seem to be measuring R^2 as your solution, is that what your C# code is using as a measure of distance from perfect?

Guvante
  • 18,775
  • 1
  • 33
  • 64