4

Here is a typical optimization formulation with MSF:

using Microsoft.SolverFoundation.Services;

SolverContext context = SolverContext.GetContext();
Model model = context.CreateModel();

//decisions
Decision xs = new Decision(Domain.Real, "Number_of_small_chess_boards");
Decision xl = new Decision(Domain.Real, "Number_of_large_chess_boards");

model.AddDecisions(xs, xl);

//constraints
model.AddConstraints("limits", 0 <= xs, 0 <= xl);
model.AddConstraint("BoxWood", 1 * xs + 3 * xl <= 200);
model.AddConstraint("Lathe", 3 * xs + 2 * xl <= 160);

//Goals
model.AddGoal("Profit", GoalKind.Maximize, 5 * xs + 20 * xl);

// This doesn't work!
// model.AddGoal("Profit", GoalKind.Maximize, objfunc(xs, xl));


Solution sol = context.Solve(new SimplexDirective());
Report report = sol.GetReport();
Console.WriteLine(report);

Is it possible to use a separate method instead of a statement like "5 * xs + 20 * xl" as goal function? For example, a method like the following? How?

// this method doesn't work!
static double objfunc(Decision x, Decision y)
{
    return 5 * x.ToDouble() + 20 * y.ToDouble();
}
pravprab
  • 2,301
  • 3
  • 26
  • 43
selmar
  • 181
  • 3
  • 14
  • Seems like `objfunc` should return a `Term` -- or maybe you just need to add the cast explicitly – Gus Feb 04 '14 at 22:36

2 Answers2

4

It is as simple as that:

 static Term objfunc(Decision x, Decision y)
        {
            return 5 * x + 20 * y;
        }

Rather than returning a double, the function has to return a Term.

Axel Kemper
  • 10,544
  • 2
  • 31
  • 54
  • How can I use decision variables in a separate method if they are defined as a set of values like: Set setMonths = new Set(Domain.IntegerRange(1,12) , "Months"); Decision dPrice = new Decision(Domain.RealNonnegative, "Price", setMonths); I can now pass dPrice as a Decision to a method, but how can I read the individual values (like dPrice[month])? I couldn't yet find a way. Thanks – selmar Feb 06 '14 at 18:40
  • Indexed Decision variables are explained here: http://nathanbrixius.wordpress.com/2011/07/18/getting-solution-values-using-solver-foundation-services/ – Axel Kemper Feb 06 '14 at 19:32
  • How can I get indexed values before executing solve()? dPrice.GetDouble(i) produces an error if I call it before solve(). – selmar Feb 06 '14 at 21:31
  • I would like to know this as well :-) – Fiffe Sep 11 '15 at 14:17
  • @Fiffe: The syntax is dPrice[i] like a typical array index access. Consult Natan Brixius' blog via the link of my comment above. – Axel Kemper Sep 12 '15 at 08:57
-1

Note The function does not return a numerical answer, but a method to evaluate the answer. If you were to recode as Term Test = 5 * x + 20 * y; String strTest = Test.ToString();

Then strTest would by something like (Add(mult(5,x), mult(20,y));