Getting solution values using Solver Foundation Services

Please note that Solver Foundation is no longer supported.

There was a question on the Solver Foundation forum about iterating through the results in a Decision. Here’s a code sample of how to do it in two simple cases.

Decision objects are either indexed or scalar. A decision with one index set is essentially a vector, two means matrix. You supply the Sets in the Decision constructor. In the code below, x is an indexed decision. If you don’t supply any sets then you have a non-indexed scalar Decision – that’s what we’re doing with y.

Once you solve the model you can use two different methods to pull out the results. The GetValues method returns an array: one for each value in an indexed decision. In this case, we have one index set that has 10 values, so GetValues will return 10 items. Each item is an array. The first element in the array is the value for the decision for the specific index. The remaining entries are the index values themselves. By running the program below you will get the idea.

Getting the values for non-indexed decisions is easy: just call the GetDouble method.

Here’s the code:

using System;
using System.Linq;
using Microsoft.SolverFoundation.Services;

namespace DecisionTest {
  class Program {
    static void Main(string[] args) {
      SolverContext context = SolverContext.GetContext();
      Model model = context.CreateModel();
      // Let's create an indexed parameter.
      Set s = new Set(Domain.Real, "s");
      Parameter p = new Parameter(Domain.Real, "p", s);
      // Here's some dummy data.
      var input = Enumerable.Range(1, 10).Select(item => new { Id = item, Value = item });
      p.SetBinding(input, "Value", "Id");
      model.AddParameter(p);

      // Let's create an indexed decision.
      Decision x = new Decision(Domain.Real, "x", s);
      model.AddDecision(x);

      // Here's a scalar decision.
      Decision y = new Decision(Domain.Real, "y");
      model.AddDecision(y);

      // Here are some dummy constraints to tie everything together. Just for fun.
      model.AddConstraint("c1", Model.ForEach(s, i => p[i] == x[i]));
      model.AddConstraint("c2", Model.Sum(Model.ForEach(s, i => x[i])) == y);

      // Extract data from the indexed decision.
      context.Solve();
      foreach (object[] value in x.GetValues()) {
        Console.WriteLine("x[{0}] = {1}", value[1], value[0]);
      }
      // Extract data from the scalar decision.
      Console.WriteLine("y = {0}", y.GetDouble());
    }
  }
}

7 comments

  1. Hi Natebrix;

    I’m working on modeling an optimization problem with MSF, which requires indexing decision variables. I’ve posted it here on stackoverflow:
    http://stackoverflow.com/questions/26077055/decision-matrix-in-microsoft-solver-foundation
    So far I’ve not been able to find and answer for my question.
    I’ve tried c# arrays for indexing decisions variables, but apparently arrays are not very well suited for indexing Decisions. I know you’re very busy with your new position at FrontlineSolvers (Congrats btw), but I’d very much appreciate it if you could just take a look at my problem.
    Thank you

  2. Unfortunately, it doesn’t work. I can’t set the initial values for a decision (Decision CA0Val = new Decision(Domain.RealNonnegative, “CA0”); CA0Val.SetInitialValue(0);), and I can’t get the values of the decisions before it solves (CA0Val.GetDouble()).

    1. Hi William,

      (Note that Solver Foundation is no longer supported by Microsoft.) I believe the behavior that you can’t get the Decision value *before* you solve is by design (because you supplied the value). You could just use a dictionary to store the values in that case.

      1. “a dictionary to store the values”? I’m trying a simple curvefit with an objective function, just like Excel solver can be set up to do in 5 minutes – other blogs I’ve read say MSF was never set to be able to use an objective function with a set of inputs. There is no simple example like this anywhere I can find.

      2. I’m afraid I don’t know enough about your problem to be able to help you further – all I’ve got is what you told me in your comment, which is why I made the suggestion I made.

        If you have an unconstrained nonlinear model you can use the CompactQuasiNewtonSolver – you can provide a function that specifies the objective, and you’ll get intermediate callbacks as it progresses. Here is a link to a small example: https://msdn.microsoft.com/en-us/library/ff871837(v=vs.93).aspx

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s