<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Nathan Brixius : C#</title><link>http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx</link><description>Tags: C#</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Writing high performance code</title><link>http://blogs.msdn.com/natbr/archive/2009/12/10/writing-high-performance-code.aspx</link><pubDate>Fri, 11 Dec 2009 04:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9935518</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9935518.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9935518</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9935518</wfw:comment><description>&lt;P&gt;During &lt;A href="http://www.hanselman.com/blog/HanselminutesPodcast191SolverFoundationAndOptimizationWithNathanBrixius.aspx" target=_blank mce_href="http://www.hanselman.com/blog/HanselminutesPodcast191SolverFoundationAndOptimizationWithNathanBrixius.aspx"&gt;Scott Hanselman's&amp;nbsp;podcast&lt;/A&gt; we briefly discussed managed code performance.&amp;nbsp; Here are a few of my thoughts about writing high performance code. In the spirit of a &lt;A href="http://www.amazon.com/Five-Dysfunctions-Team-Leadership-Lencioni/dp/0787960756/ref=pd_sim_b_1" target=_blank mce_href="http://www.amazon.com/Five-Dysfunctions-Team-Leadership-Lencioni/dp/0787960756/ref=pd_sim_b_1"&gt;cheesy business book&lt;/A&gt; (or &lt;A href="http://www.hulu.com/watch/4183/saturday-night-live-down-by-the-river" target=_blank mce_href="http://www.hulu.com/watch/4183/saturday-night-live-down-by-the-river"&gt;motivational speaker&lt;/A&gt;), I will give away my main points in the form of controversial-sounding statements before proceeding to flog them to death:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Don't trust anyone.&lt;/LI&gt;
&lt;LI&gt;Managed is better.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Some background: before I came to Microsoft I built solvers for both discrete and continuous optimization problems, primarily in C/C++, with a bit of Fortran thrown in.&amp;nbsp; Back in 2002 when I was on the &lt;A href="http://blogs.msdn.com/project/" mce_href="http://blogs.msdn.com/project/"&gt;Project Server&lt;/A&gt; team we were faced with the decision of whether to rebuild our scheduling engine in C++ or C#.&amp;nbsp; For the past year or so I have worked on the &lt;A href="http://www.solverfoundation.com/" target=_blank mce_href="http://www.solverfoundation.com"&gt;Solver Foundation&lt;/A&gt; team, which is pure C#.&amp;nbsp; We build solvers that solve a range of large-scale optimization problems, and they are “industrial grade”:&amp;nbsp; tens or hundreds of thousands of constraints are not uncommon.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Don't trust anyone.&lt;/STRONG&gt; &lt;A href="http://blogs.msdn.com/ricom" mce_href="http://blogs.msdn.com/ricom"&gt;Rico Mariani&lt;/A&gt; says the first rule of performance is to measure.&amp;nbsp; &lt;A href="http://blogs.msdn.com/ricom/archive/2003/12/02/40779.aspx" target=_blank mce_href="http://blogs.msdn.com/ricom/archive/2003/12/02/40779.aspx"&gt;Listen to Rico&lt;/A&gt;.&amp;nbsp; There are many reasons for this.&amp;nbsp; The first is that nobody has ever written code that is doing exactly what you are trying to do.&amp;nbsp; Otherwise (being a smart programmer) you should just call their code or (being a smart business person) you should just buy their code, try to do it better, or do something different entirely (perhaps mixed martial arts).&amp;nbsp; So you should seek to understand how the code behaves, otherwise you will never find out - until it is too late.&lt;/P&gt;
&lt;P&gt;The second is that you know your scenarios and priorities better than others do.&amp;nbsp; You should already&amp;nbsp;have an idea of how fast the code is supposed to be. Now sometimes the requirement truly is "make it as fast as possible".&amp;nbsp; For numerical libraries this is often the case because many problems can be made to be arbitrarily complicated.&amp;nbsp; For example, if you are modeling fluid dynamics you could use tighter meshes and get more accurate results.&amp;nbsp; In most other cases (perhaps in a user interface) you have a hard number you need to hit. Of course, there are some simple guidelines that may apply in most situations.&amp;nbsp; If you never go to the database, your server app will be fast. If you never allocate memory, your numeric code will fly. True or false? Well…measure.&lt;/P&gt;
&lt;P&gt;The third is that even if someone else has measured code that seems to be similar to yours, their results may be misleading.&amp;nbsp; For example, you depend on different collection classes, or you are running on a different processor.&amp;nbsp; Or your input data is different in some subtle way.&amp;nbsp; To take a very simple example, suppose you want to sort lists of 1 million integers, and somebody says, "hey, I measured different sorting algorithms on arrays of 1 million integers and quicksort is best."&amp;nbsp; And they hand over the code and all of their results.&amp;nbsp; Well, what do those arrays look like?&amp;nbsp; Because if the data is mostly sorted then something like insertion sort may work better.&lt;/P&gt;
&lt;P&gt;If you follow this advice you may end up with more questions: doesn't this take a lot of time and effort? How do I know when to stop measuring, or stop optimizing my code?&amp;nbsp; If you start profiling at the very start of development, and build some simple skills, it's not too bad (and you learn a lot).&amp;nbsp; If, for example, you are considering whether to use managed or unmanaged code for a project, prototype a couple of key sections in C++ and C# and measure.&amp;nbsp; I did this on the Project Server team and that was the best way to settle the argument.&amp;nbsp; These things often get way too philosophical – just try it and see.&amp;nbsp; I did standard critical path scheduling in both C# and C++ and found that the C# version was only 10-15% slower.&amp;nbsp; We went with C# and in the course of development we were able to find algorithmic improvements that resulted in a faster implementation that the original C++ codebase. Get good at writing simple programs that answer one specific performance question.&amp;nbsp; For example: should I use a list or an array?&amp;nbsp; How should I read this data set?&amp;nbsp; Be a scientist and seek to answer specific questions by controlling the conditions and varying only one thing at a time.&amp;nbsp; And pick the right thing based on your knowledge of the customer scenario.&amp;nbsp;&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;STRONG&gt;Managed or unmanaged?&lt;/STRONG&gt; My blunt opinion is: unless your computation is dominated by &lt;A href="http://www.netlib.org/blas/" target=_blank mce_href="http://www.netlib.org/blas/"&gt;BLAS&lt;/A&gt;-style computations you are better off using C# because of productivity, stability, and maintainability concerns.&amp;nbsp; &lt;BR&gt;&amp;nbsp;&lt;BR&gt;Here are a couple of “pros” for C#:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;There are clear performance differences, but in many cases when you look at the overall system performance they can be washed away due to other factors: I/O, a webservice call, DB access, etc.&lt;/LI&gt;
&lt;LI&gt;Many programmers (myself included) are much more productive writing C# code.&amp;nbsp; This gives me more time to investigate possible algorithmic improvements, write good unit tests, etc. There are opportunity costs!&lt;/LI&gt;
&lt;LI&gt;I&amp;nbsp;think it is easier to make use of multiple cores. For example, the parallel extensions available for .Net 3.5 (and built into 4.0) are very easy to use.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;There are also some clear downsides:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;It is easy to get lazy, or to unintentionally use constructs that are not efficient.&amp;nbsp; People start using List&amp;lt;&amp;gt; and Dictionary&amp;lt;&amp;gt; when a good ol’ array will do.&amp;nbsp; It’s also easy to miss unnecessary memory allocations, because everything is garbage collected.&amp;nbsp; So you need to be vigilant about profiling the code.&lt;/LI&gt;
&lt;LI&gt;There is a lot of unnecessary array bounds checking that slows things down.&amp;nbsp; In particular, with &lt;A href="http://www.netlib.org/lapack/" target=_blank mce_href="http://www.netlib.org/lapack/"&gt;LAPACK&lt;/A&gt;-style routines with tight, nested loops.&lt;/LI&gt;
&lt;LI&gt;As far as I know, the managed code compilers do not make use of SSE2 instructions.&amp;nbsp;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Others have different opinions and I’m not saying they’re wrong - so long as they have measured.&amp;nbsp; Otherwise they are bullshitting you.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9935518" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Project/default.aspx">Project</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx">Solver Foundation</category></item><item><title>Solver Foundation on Hanselminutes</title><link>http://blogs.msdn.com/natbr/archive/2009/12/09/solver-foundation-on-hanselminutes.aspx</link><pubDate>Wed, 09 Dec 2009 15:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9934634</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9934634.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9934634</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9934634</wfw:comment><description>&lt;P&gt;The latest edition of &lt;A href="http://www.hanselman.com/blog/" mce_href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/A&gt;'s &lt;A href="http://www.hanselminutes.com/default.aspx?showID=209" mce_href="http://www.hanselminutes.com/default.aspx?showID=209"&gt;Hanselminutes&lt;/A&gt; podcast features yours truly.&amp;nbsp; We talked about Solver Foundation, numerical optimization, and good old-fashioned code optimization.&amp;nbsp; Scott's a great guy and doing the podcast was a lot of fun.&lt;/P&gt;
&lt;P&gt;Those of you new to Solver Foundation (or this blog) may be curious about what you can actually do with Solver Foundation. Here is the &lt;A href="http://code.msdn.microsoft.com/solverfoundation/Release/ProjectReleases.aspx?ReleaseId=1799" mce_href="http://code.msdn.microsoft.com/solverfoundation/Release/ProjectReleases.aspx?ReleaseId=1799"&gt;download location&lt;/A&gt; for the free&amp;nbsp;Express version of Solver Foundation.&amp;nbsp; I hope that by listening to the podcast you already know the basics, so here are a few code-oriented posts:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Here is a short description of “&lt;A href="http://blogs.msdn.com/natbr/archive/2009/10/08/announcing-solver-foundation-2-0.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/10/08/announcing-solver-foundation-2-0.aspx"&gt;what’s new&lt;/A&gt;” in our 2.0 release.&lt;/LI&gt;
&lt;LI&gt;Here is a &lt;A href="http://blogs.msdn.com/natbr/archive/2009/04/27/solving-traveling-salesman-problems-using-solver-foundation.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/04/27/solving-traveling-salesman-problems-using-solver-foundation.aspx"&gt;C# sample&lt;/A&gt; that solves traveling salesman problems.&lt;/LI&gt;
&lt;LI&gt;Here is a &lt;A href="http://blogs.msdn.com/natbr/archive/2009/05/05/creating-parameterized-solver-foundation-models-using-linq-to-sql.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/05/05/creating-parameterized-solver-foundation-models-using-linq-to-sql.aspx"&gt;LINQ to SQL&lt;/A&gt; sample using Solver Foundation.&lt;/LI&gt;
&lt;LI&gt;Here is an&lt;A href="http://blogs.msdn.com/lengningliu/archive/2009/09/04/optimization-domain-specific-language-in-f-with-units-of-measure.aspx" mce_href="http://blogs.msdn.com/lengningliu/archive/2009/09/04/optimization-domain-specific-language-in-f-with-units-of-measure.aspx"&gt; F# sample&lt;/A&gt;.&amp;nbsp; The F# integration features a domain specific language for creating optimization problems.&amp;nbsp; It also supports “units of measure”, meaning you can associate real-life units such as miles, gallons, dollars, or touchdowns to parameters and decisions.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://yetanothermathprogrammingconsultant.blogspot.com/" mce_href="http://yetanothermathprogrammingconsultant.blogspot.com/"&gt;Erwin&lt;/A&gt; did a really nice post on doing &lt;A href="http://yetanothermathprogrammingconsultant.blogspot.com/2009/07/ms-solver-foundation-excel-interface.html" mce_href="http://yetanothermathprogrammingconsultant.blogspot.com/2009/07/ms-solver-foundation-excel-interface.html"&gt;portfolio management&lt;/A&gt; using Solver Foundation and Excel.&amp;nbsp; I like the visuals.&amp;nbsp; In fact Erwin's site has a number of great samples and documents.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;And I'd be remiss if I didn't mention that Solver Foundation ships with TONS of samples that span languages, scenarios, and solvers.&lt;/P&gt;
&lt;P&gt;The last part of our conversation was about writing high-performance code.&amp;nbsp;I'll share some thoughts about that later this week.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9934634" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx">combinatorial optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx">Solver Foundation</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/project+scheduling/default.aspx">project scheduling</category><category domain="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx">operations research</category><category domain="http://blogs.msdn.com/natbr/archive/tags/interior+point+methods/default.aspx">interior point methods</category><category domain="http://blogs.msdn.com/natbr/archive/tags/self+promotion/default.aspx">self promotion</category></item><item><title>Controlling Simplex and IPM termination conditions</title><link>http://blogs.msdn.com/natbr/archive/2009/11/30/controlling-simplex-and-ipm-termination-conditions.aspx</link><pubDate>Mon, 30 Nov 2009 21:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9930388</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9930388.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9930388</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9930388</wfw:comment><description>&lt;P&gt;On our MSDN message board there was a question about how to control when the SimplexSolver aborts.&amp;nbsp; You can do this by providing an abort callback to the params object sent to the solver.&amp;nbsp; For example, to terminate after 100ms:&lt;/P&gt;&lt;PRE&gt;    private static void PetrochemLinearModel() {
      SimplexSolver solver = new SimplexSolver();
      int sa, vz;
      solver.AddVariable("SA", out sa);
      solver.SetBounds(sa, 0, 9000);
      solver.AddVariable("VZ", out vz);
      solver.SetBounds(vz, 0, 6000);

      int goal;
      solver.AddRow("goal", out goal);
      solver.AddGoal(goal, 0, true);
      solver.SetCoefficient(goal, sa, 20);
      solver.SetCoefficient(goal, vz, 15);

      int demand1, demand2, demand3;
      solver.AddRow("demand1", out demand1);
      solver.SetCoefficient(demand1, sa, 0.3);
      solver.SetCoefficient(demand1, vz, 0.4);
      solver.SetLowerBound(demand1, 1126);

      solver.AddRow("demand2", out demand2);
      solver.SetCoefficient(demand2, sa, 0.4);
      solver.SetCoefficient(demand2, vz, 0.2);
      solver.SetLowerBound(demand2, 1500);

      solver.AddRow("demand3", out demand3);
      solver.SetCoefficient(demand3, sa, 0.2);
      solver.SetCoefficient(demand3, vz, 0.3);
      solver.SetLowerBound(demand3, 500);

      Stopwatch s = new Stopwatch();
      var param = new SimplexSolverParams(() =&amp;gt; s.ElapsedMilliseconds &amp;gt; 100);
      s.Start();
      var solution = solver.Solve(param);
      Console.WriteLine(solution.LpResult);
      Console.WriteLine("goal = " + solution.GetValue(goal).ToDouble());
      Console.WriteLine("sa   = " + solution.GetValue(sa).ToDouble());
      Console.WriteLine("vz   = " + solution.GetValue(vz).ToDouble());
    }
&lt;/PRE&gt;
&lt;P&gt;If you are using the InteriorPointSolver,&amp;nbsp;the callback can reference&amp;nbsp;solver properties (including iteration count and duality gap) to do more sophisticated stuff.&amp;nbsp; For example:&lt;/P&gt;&lt;PRE&gt;      var param = new InteriorPointSolverParams();
      param.IterationStartedCallback = () =&amp;gt; {
        Console.WriteLine("{0}\t{1:f6} {2:e6}", solver.IterationCount, solver.Primal, solver.Gap.ToDouble());
        return false;
      };
      var solution = solver.Solve(param);
&lt;/PRE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9930388" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx">Solver Foundation</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx">operations research</category><category domain="http://blogs.msdn.com/natbr/archive/tags/interior+point+methods/default.aspx">interior point methods</category></item><item><title>Using Solver Foundation's Unconstrained Nonlinear Solver</title><link>http://blogs.msdn.com/natbr/archive/2009/10/15/using-solver-foundation-s-unconstrained-nonlinear-solver.aspx</link><pubDate>Thu, 15 Oct 2009 22:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9907880</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9907880.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9907880</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9907880</wfw:comment><description>&lt;P&gt;Hey, did you know that Solver Foundation can solve unconstrained nonlinear optimization problems?&amp;nbsp; Yep, it's true.&amp;nbsp; Few people know about it because 1) we haven't talked about it too much and 2) it is not accessible from the SFS (which means you can't use OML or the Excel add-in to solve such problems).&amp;nbsp; To use the solver you need to work with a solver object directly.&amp;nbsp; The Samples directory contains a simple example, but since there has been a &lt;A href="http://code.msdn.microsoft.com/solverfoundation/Thread/View.aspx?ThreadId=2229" mce_href="http://code.msdn.microsoft.com/solverfoundation/Thread/View.aspx?ThreadId=2229"&gt;couple&lt;/A&gt; &lt;A href="http://code.msdn.microsoft.com/solverfoundation/Thread/View.aspx?ThreadId=2309" target=_blank mce_href="http://code.msdn.microsoft.com/solverfoundation/Thread/View.aspx?ThreadId=2309"&gt;of&lt;/A&gt; &lt;A href="http://code.msdn.microsoft.com/solverfoundation/Thread/View.aspx?ThreadId=2389" target=_blank mce_href="http://code.msdn.microsoft.com/solverfoundation/Thread/View.aspx?ThreadId=2389"&gt;requests&lt;/A&gt; I thought I would give a slighly more involved example.&lt;/P&gt;
&lt;P&gt;The CompactQuasiNewtonSolver class solves unconstrained optimization problems: it finds the minimum (or maximum) of an unbound objective function f(x).&amp;nbsp; x is an array of doubles, and f needs to be twice differentiable.&amp;nbsp; The CQN solver uses the &lt;A href="http://en.wikipedia.org/wiki/BFGS" target=_blank mce_href="http://en.wikipedia.org/wiki/BFGS"&gt;L-BFGS&lt;/A&gt; algorithm.&amp;nbsp; Like other implementations, you need to provide a function that will serve up the function value and gradient on demand, given the variables x.&amp;nbsp; To do that, set the GradientAndValueAtPoint property to a delegate that fills in the gradient, and returns the function value.&amp;nbsp; You'll also need to specify a starting point.&lt;/P&gt;
&lt;P&gt;The CompactQuasiNewtonSolver has a Solve method that takes a solver parameters object.&amp;nbsp; It has a few interesting properties, including the solver tolerance and maximum iteration count.&amp;nbsp; On construction you can also pass in an "abort" delegate.&amp;nbsp; This function will be called periodically during the course of execution - if you return true then the solver will return.&amp;nbsp; In my sample below, I abuse it to print out the progress of the solver as it proceeds.&amp;nbsp; Note that I would have liked to have used solver.NumberOfIterations rather than keeping track of the number of calls myself.&amp;nbsp; That's a bug, and it will get fixed in our 2.1 release.&lt;/P&gt;
&lt;P&gt;The function can have as many variables as you like.&amp;nbsp; In my example I am minimizing a multidimensional variant of the Rosenbrock function, a standard test problem.&amp;nbsp; You can modify the code to use your own objective function by modifying the ValueAndGradient method.&amp;nbsp; You can also learn more about the solver by consulting the Solver Programming Primer (page 24 or so).&lt;/P&gt;&lt;PRE&gt;using System;
using Microsoft.SolverFoundation.Solvers;

namespace Microsoft.SolverFoundation.Samples {
  /// &amp;lt;summary&amp;gt; Minimizes the generalized Rosenbrock function, a standard test case
  /// in nonlinear optimization. You can read more about the Rosenbrock
  /// function here:
  ///  http://en.wikipedia.org/wiki/Rosenbrock_function
  /// &amp;lt;/summary&amp;gt;
  public class Rosenbrock {
    public static void Main(string[] args) {

      int n = 4; // make sure I'm even, see below.
      double[] x = new double[n];
      for (int i = 0; i &amp;lt; x.Length; i++) {
        x[i] = -1;
      }

      CompactQuasiNewtonSolver solver = new CompactQuasiNewtonSolver(n);
      int iterationCount = 0;
      CompactQuasiNewtonSolverParams param = new CompactQuasiNewtonSolverParams(() =&amp;gt; {
        Console.WriteLine("{0} | {1:e6}", /*solver.NumberOfIterations*/ iterationCount++, solver.ToleranceDifference);
        return false;
      }
        );
      
      solver.SetStartingPoint(x);
      solver.GradientAndValueAtPoint = (GetGradientAndValueAtPoint)ValueAndGradient;
      solver.Minimize = true;

      var solutionQuality = solver.Solve(param);

      Console.WriteLine();
      Console.WriteLine("Solution quality = " + solutionQuality);
      Console.WriteLine("f(x) = " + solver.SolutionValue);
      solver.GetSolutionPoint(x);
      for (int i = 0; i &amp;lt; x.Length; i++) {
        Console.WriteLine("x[{0}] = {1}", i, x[i]);
      }
    }

    /// &amp;lt;summary&amp;gt;Get the function value and gradient for the specified point.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="x"&amp;gt;The point at which the value and gradient should be computed.&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="gradient"&amp;gt;The gradient vector, the same size as x.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;The function value.&amp;lt;/returns&amp;gt;
    private static double ValueAndGradient(double[] x, double[] gradient) {
      // The gradient and value are both computed inside the method for efficiency.
      // It's also possible to refactor value and gradient calculation into submethods.
      double value = 0;
      for (int j = 0; j &amp;lt; x.Length; j += 2) {
        double t1 = 1.0 - x[j];
        double t2 = 10.0 * (x[j + 1] - x[j] * x[j]);
        gradient[j + 1] = 20.0 * t2;
        gradient[j] = -2.0 * (x[j] * gradient[j + 1] + t1);
        value += t1 * t1 + t2 * t2;
      }
      return value;
    }
  }
}
&lt;/PRE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9907880" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx">Solver Foundation</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx">operations research</category></item><item><title>Solver Foundation 2.0 Preview: Second Order Conic Programming</title><link>http://blogs.msdn.com/natbr/archive/2009/10/01/solver-foundation-2-0-preview-second-order-conic-programming.aspx</link><pubDate>Fri, 02 Oct 2009 07:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9902217</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9902217.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9902217</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9902217</wfw:comment><description>&lt;P&gt;&lt;A href="http://blogs.msdn.com/natbr/archive/2009/09/03/solver-foundation-2-0-preview-simulation-and-stochastic-programming.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/09/03/solver-foundation-2-0-preview-simulation-and-stochastic-programming.aspx"&gt;A couple of weeks ago&lt;/A&gt; I wrote about one of our big features for Solver Foundation 2.0: &lt;A href="http://blogs.msdn.com/natbr/archive/2009/09/03/solver-foundation-2-0-preview-simulation-and-stochastic-programming.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/09/03/solver-foundation-2-0-preview-simulation-and-stochastic-programming.aspx"&gt;stochastic programming&lt;/A&gt;. In this post I want to talk about a new solver for 2.0: an interior-point solver for &lt;A href="http://en.wikipedia.org/wiki/Second-order_cone_programming" target=_blank mce_href="http://en.wikipedia.org/wiki/Second-order_cone_programming"&gt;Second Order Conic Programming&lt;/A&gt; (SOCP). Second Order Conic Programming is the problem of minimizing a linear function where there are linear terms constrained to be inside a second order cone. Also called conic quadratic programming, SOCP is important because it can be used to model many real-world robust optimization, engineering, and finance problems. You can even model certain types of chance constraints using SOCP.&amp;nbsp; Here are a few favorite SOCP links:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://en.wikipedia.org/wiki/Second-order_cone_programming" target=_blank mce_href="http://en.wikipedia.org/wiki/Second-order_cone_programming"&gt;SOCP on wikipedia&lt;/A&gt;.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://stanford.edu/~boyd/papers/socp.html" target=_blank mce_href="http://stanford.edu/~boyd/papers/socp.html"&gt;Lobo, Vandenberghe, Boyd &amp;amp; Lebret's paper&lt;/A&gt; has several applications.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://citeseer.ist.psu.edu/old/alizadeh02secondorder.html" target=_blank mce_href="http://citeseer.ist.psu.edu/old/alizadeh02secondorder.html"&gt;Alizadeh and Goldfarb's paper&lt;/A&gt; is also excellent.&lt;/LI&gt;
&lt;LI&gt;Cornuejols and Tutuncu's book &lt;A href="http://www.cambridge.org/us/catalogue/catalogue.asp?isbn=9780521861700" mce_href="http://www.cambridge.org/us/catalogue/catalogue.asp?isbn=9780521861700"&gt;Optimization Methods in Finance&lt;/A&gt; has a couple of chapters on conic optimization.&lt;/LI&gt;
&lt;LI&gt;If you want to get truly hardcore, &lt;A href="http://www2.isye.gatech.edu/~nemirovs/" target=_blank mce_href="http://www2.isye.gatech.edu/~nemirovs/"&gt;Nemirovski&lt;/A&gt; and &lt;A href="http://www.ee.ucla.edu/~vandenbe/index.html" target=_blank mce_href="http://www.ee.ucla.edu/~vandenbe/index.html"&gt;Vandenberghe&lt;/A&gt; have great notes posted online.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;An SOCP can contain conventional linear constraints Ax &amp;gt;= b as well as second-order cone constraints. &lt;A href="http://www.solver.com/sdkplatform7.htm" target=_blank mce_href="http://www.solver.com/sdkplatform7.htm"&gt;Some&lt;/A&gt; &lt;A href="http://mosek.com/" target=_blank mce_href="http://mosek.com/"&gt;solvers&lt;/A&gt; define SOCP in terms of conic variables rather than conic constraints. Solver Foundation’s interior point solver uses conic constraints rather than conic variables because (IMHO) it leads to a more flexible, easy-to-program solver API. A second-order cone is a pointed cone where the norm of n - 1 variables t_i&amp;nbsp; is less than the other variable t_0 (so that a cross-section is a circle): t_0 &amp;gt;= || t_i ||, t_0 &amp;gt;= 0. A second-order cone in three dimensions looks like an ice cream cone. A second-order conic constraint is similar, except that each t can be a linear term that may combine several variables. The first term t_0 is called the "primary row".&lt;/P&gt;
&lt;P&gt;What this means is that if you know how to build linear programming problems using the ILinearModel API I described &lt;A href="http://blogs.msdn.com/natbr/archive/2009/09/24/using-the-solver-foundation-interior-point-solver.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/09/24/using-the-solver-foundation-interior-point-solver.aspx"&gt;last time&lt;/A&gt;, then you pretty much know how to build SOCP problems.&amp;nbsp; You need to build a row that represents the conic constraint using AddRow, then you need to call AddRow once for each term in the conic constraint.&amp;nbsp; That's it.&lt;/P&gt;
&lt;P&gt;Here's a short code sample: given an InteriorPointSolver, pass in a list of matrices F and a corresponding list of matrices g.&amp;nbsp; We want to find a vector x that minimizes the sum of ||Fx + g|| over all entries in F and g.&amp;nbsp; The steps are as follows:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Create an InteriorPointSolver and the lists&amp;nbsp;F and g.&amp;nbsp;&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;Create the descision variables x, and add the goal just as in my &lt;A href="http://blogs.msdn.com/natbr/archive/2009/09/24/using-the-solver-foundation-interior-point-solver.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/09/24/using-the-solver-foundation-interior-point-solver.aspx"&gt;previous post&lt;/A&gt;. &lt;/LI&gt;
&lt;LI&gt;Iterate through the matrices.&amp;nbsp; We will create one conic inequality for each matrix.&amp;nbsp; The primary row is an artificial variable t, which is an upper bound on the norm of Fx + g.&amp;nbsp; The other rows are simply the rows of F, with the bounds coming from g.&lt;/LI&gt;&lt;/UL&gt;&lt;PRE&gt;/// &amp;lt;summary&amp;gt; Create a simple sum-of-norms problem from F and g.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;remarks&amp;gt;Returns the variable vids so the solution vector x can be 
/// retrieved after Solve().&amp;lt;/remarks&amp;gt;
private static int[] BuildSumOfNorms(InteriorPointSolver solver, 
  List&amp;lt;double[][]&amp;gt; F, List&amp;lt;double[]&amp;gt; g) {

  int[] x = new int[F[0][0].Length];
  for (int i = 0; i &amp;lt; x.Length; i++) {
    solver.AddVariable("x" + i, out x[i]);
  }

  // Add the goal.
  int goal;
  solver.AddRow("goal", out goal);
  solver.AddGoal(goal, 1, true);
  for (int k = 0; k &amp;lt; F.Count; k++) {
    int cone, t;
    // Add variable t_k, which is the upper bound on the kth norm.
    solver.AddVariable("t_" + k, out t);
    solver.SetCoefficient(goal, t, Rational.One);
    solver.SetBounds(t, Rational.Zero, Rational.PositiveInfinity);

    // Add a quadratic cone.
    solver.AddRow("cone_" + k, SecondOrderConeType.Quadratic, out cone);
    solver.SetBounds(cone, 0, Rational.PositiveInfinity);

    // Add the conic constraint
    int conicRow1;
    solver.AddRow("cr1_" + k, cone, SecondOrderConeRowType.PrimaryConic, 
      out conicRow1);
    solver.SetCoefficient(conicRow1, t, Rational.One);
    solver.SetLowerBound(conicRow1, Rational.Zero);

    for (int i = 0; i &amp;lt; F[k].Length; i++) {
      int conicRow2;
      solver.AddRow("cr2_" + k + "_" + i, cone, SecondOrderConeRowType.Conic, 
        out conicRow2);
      for (int j = 0; j &amp;lt; F[k][i].Length; j++) {
        if (F[k][i][j] != 0) {
          solver.SetCoefficient(conicRow2, x[j], F[k][i][j]);
        }
      }
      solver.SetLowerBound(conicRow2, -g[k][i]);
    }
  }

  return x;
}
&lt;/PRE&gt;
&lt;P&gt;Those are the basics. We will have SOCP analogues of the LinearModel APIs, as well as APIs that let you look at the details of the conic constraints. In Version 2.0 we will support creation and solution of SOCP only using the InteriorPointSolver API.&amp;nbsp; We will not have SFS or OML support for this release.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9902217" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx">Solver Foundation</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx">operations research</category><category domain="http://blogs.msdn.com/natbr/archive/tags/interior+point+methods/default.aspx">interior point methods</category><category domain="http://blogs.msdn.com/natbr/archive/tags/SOCP/default.aspx">SOCP</category></item><item><title>Using the Solver Foundation Interior Point Solver</title><link>http://blogs.msdn.com/natbr/archive/2009/09/24/using-the-solver-foundation-interior-point-solver.aspx</link><pubDate>Fri, 25 Sep 2009 00:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9899162</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9899162.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9899162</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9899162</wfw:comment><description>I've had a few requests on this topic, so I thought I would give a simple example of how to write code against Solver Foundation's interior point solver. If you are new to Solver Foundation, be warned that this is something of an "advanced topic". The most complete, powerful Solver Foundation programming interface is Solver Foundation Services. The &lt;A href="http://solverfoundation.com/"&gt;solverfoundation.com&lt;/A&gt; site has links to more information about the SFS, and I have worked through several samples on this blog: &lt;A href="http://blogs.msdn.com/natbr/archive/2009/04/24/modeling-a-production-planning-problem-using-solver-foundation.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/04/24/modeling-a-production-planning-problem-using-solver-foundation.aspx"&gt;production planning&lt;/A&gt;, &lt;A href="http://blogs.msdn.com/natbr/archive/2008/12/19/two-way-data-binding-using-linq-and-solver-foundation-services.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2008/12/19/two-way-data-binding-using-linq-and-solver-foundation-services.aspx"&gt;two-way data binding&lt;/A&gt;, &lt;A href="http://blogs.msdn.com/natbr/archive/2009/04/27/solving-traveling-salesman-problems-using-solver-foundation.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/04/27/solving-traveling-salesman-problems-using-solver-foundation.aspx"&gt;traveling salesman&lt;/A&gt;, &lt;A href="http://blogs.msdn.com/natbr/archive/2009/05/05/creating-parameterized-solver-foundation-models-using-linq-to-sql.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/05/05/creating-parameterized-solver-foundation-models-using-linq-to-sql.aspx"&gt;parameterized models&lt;/A&gt;, &lt;A href="http://blogs.msdn.com/natbr/archive/2009/06/02/solver-foundation-linq-to-sql-example.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/06/02/solver-foundation-linq-to-sql-example.aspx"&gt;LINQ-to-SQL&lt;/A&gt;. 
&lt;P mce_keep="true"&gt;The InteriorPointSolver class is capable of solving linear, quadratic, and (in our upcoming 2.0 release) second order conic optimization problems. Let's take as an example the production planning problem I wrote about in a &lt;A href="http://blogs.msdn.com/natbr/archive/2009/04/24/modeling-a-production-planning-problem-using-solver-foundation.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/04/24/modeling-a-production-planning-problem-using-solver-foundation.aspx"&gt;previous post&lt;/A&gt;.&amp;nbsp; It is a simple linear programming problem with two decisions (the production for each refinery) and three constraints (the demand for each refined product). In our SFS sample we simply declared the decisions, goals, and constraints and expressed them algebraically using the SolverContext and Model. The InteriorPointSolver class represents linear models in a slightly different way: using variables and rows. Variables are the analogue of SFS Decisions, whereas rows can represent either goals or constraints. Both variables and rows can have upper and/or lower bounds. In a linear model, both goals and constraints consist of linear combinations of variables, such as "3*x + 4*y + 5*z". Whereas in the SFS we can express these terms very naturally, with the InteriorPointSolver, the terms are expressed one at a time by specifying the coefficient associated with each variable in the row. Here is the C# code:&lt;/P&gt;&lt;PRE&gt;  private static void PetrochemLinearModel() {
    InteriorPointSolver solver = new InteriorPointSolver();
    int sa, vz;
    solver.AddVariable("SA", out sa);
    solver.SetBounds(sa, 0, 9000);
    solver.AddVariable("VZ", out vz);
    solver.SetBounds(vz, 0, 6000);

    int goal;
    solver.AddRow("goal", out goal);
    solver.AddGoal(goal, 0, true);
    solver.SetCoefficient(goal, sa, 20);
    solver.SetCoefficient(goal, vz, 15);

    int demand1, demand2, demand3;
    solver.AddRow("demand1", out demand1);
    solver.SetCoefficient(demand1, sa, 0.3);
    solver.SetCoefficient(demand1, vz, 0.4);
    solver.SetLowerBound(demand1, 1126);

    solver.AddRow("demand2", out demand2);
    solver.SetCoefficient(demand2, sa, 0.4);
    solver.SetCoefficient(demand2, vz, 0.2);
    solver.SetLowerBound(demand2, 1500);

    solver.AddRow("demand3", out demand3);
    solver.SetCoefficient(demand3, sa, 0.2);
    solver.SetCoefficient(demand3, vz, 0.3);
    solver.SetLowerBound(demand3, 500);

    var param = new InteriorPointSolverParams();
    var solution = solver.Solve(param);
    Console.WriteLine("goal = " + solution.GetValue(goal).ToDouble());
    Console.WriteLine("sa   = " + solution.GetValue(sa).ToDouble());
    Console.WriteLine("vz   = " + solution.GetValue(vz).ToDouble());
  }
&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;You'll also need to add "using Microsoft.SolverFoundation.Common;" and "using Microsoft.SolverFoundation.Solvers;" to the top of your program. Extending this code to solve a quadratic program is easy: there is an overload of SetCoefficient that takes two variables as input. In my next post I will talk about second order conic programming, and a few other improvements in the 2.0 version of the InteriorPointSolver.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9899162" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx">Solver Foundation</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx">operations research</category><category domain="http://blogs.msdn.com/natbr/archive/tags/interior+point+methods/default.aspx">interior point methods</category></item><item><title>Quadratic Assignment Problems: solution enumeration</title><link>http://blogs.msdn.com/natbr/archive/2009/07/27/quadratic-assignment-problems-solution-enumeration.aspx</link><pubDate>Mon, 27 Jul 2009 19:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9850185</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9850185.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9850185</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9850185</wfw:comment><description>&lt;P&gt;In the last few posts we have given code for computing the &lt;A href="http://blogs.msdn.com/natbr/archive/2008/07/10/quadratic-assignment-problems-bounds.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2008/07/10/quadratic-assignment-problems-bounds.aspx"&gt;Gilmore Lawler bound&lt;/A&gt; for quadratic assignment problems, and &lt;A href="http://blogs.msdn.com/natbr/archive/2009/07/19/quadratic-assignment-problems-strong-and-weak-branching.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/07/19/quadratic-assignment-problems-strong-and-weak-branching.aspx"&gt;described two different branching techniques&lt;/A&gt;.&amp;nbsp;&amp;nbsp; In this post we show how to enumerate solutions of a small QAP.&amp;nbsp; The possible solutions to a QAP range over permutations over unassigned facilities and locations.&amp;nbsp;&amp;nbsp; If lower bounds do not increase after repeated branching, we may eventually assign nearly all the facilities to locations.&amp;nbsp; If there are only 2 or 3 remaining, we may as well just enumerate all the possible solutions and pick the best.&amp;nbsp;&amp;nbsp; In practice, we hope that we will rarely have to do this, otherwise the branch-and-bound tree will be too large to process efficiently.&amp;nbsp; Here is a procedure that enumerates over all solutions of a size 3 QAP.&amp;nbsp; Iterating over permutations is a standard textbook problem, so maybe you can write cleaner code than I did here!&lt;BR&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; Assume that all facilities have been assigned to locations, &lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; except three. EnumerateSolutions enumerates all six remaining assignments &lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; returns the best.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; EnumerateSolutions(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;Qap&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; q, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchAndBoundNode&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; node, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[] pBest) {&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; objBest;&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; nPerm = perm3.GetLength(0);&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; n = perm3.GetLength(1);&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[] obj = &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[nPerm];&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[] r = node.p.UnusedIndices().ToArray();&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[] c = node.pInv.UnusedIndices().ToArray();&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[] p = (&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[])node.p.Clone();&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;Debug&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;.Assert(r.Length == n, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;"Only call me for size "&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; + n + &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;" QAPs."&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;);&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;// Try all the possible permutations.&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;for&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; (&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; i = 0; i &amp;lt; nPerm; i++) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;for&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; (&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; j = 0; j &amp;lt; n; j++) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p[r[j]] = c[perm3[i, j]]; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; obj[i] = q.Evaluate(p);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;// Get the best permutation and objective.&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; best = obj.ArgMin(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;out&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; objBest);&lt;BR&gt;&amp;nbsp; p.CopyTo(pBest, 0);&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;for&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; (&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; j = 0; j &amp;lt; n; j++) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pBest[r[j]] = perm3[best, j];&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; objBest;&lt;BR&gt;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;If you combine the code from the following posts you will see that we almost have a working B&amp;amp;B solver:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;&lt;A href="http://blogs.msdn.com/natbr/archive/2007/08/09/linear-assignment-problems-part-iii.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2007/08/09/linear-assignment-problems-part-iii.aspx"&gt;Linear assignment problem solver&lt;/A&gt;.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;&lt;A href="http://blogs.msdn.com/natbr/archive/2008/05/03/quadratic-assignment-problems-branch-and-bound.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2008/05/03/quadratic-assignment-problems-branch-and-bound.aspx"&gt;QAP object&lt;/A&gt;.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;&lt;A href="http://blogs.msdn.com/natbr/archive/2008/07/10/quadratic-assignment-problems-bounds.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2008/07/10/quadratic-assignment-problems-bounds.aspx"&gt;QAP Gilmore-Lawler bound&lt;/A&gt;.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;&lt;A href="http://blogs.msdn.com/natbr/archive/2009/03/23/branch-and-bound-algorithms-for-qap.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/03/23/branch-and-bound-algorithms-for-qap.aspx"&gt;Branch-and-bound skeleton&lt;/A&gt;.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;&lt;A href="http://blogs.msdn.com/natbr/archive/2009/03/24/simple-matrix-vector-permutation-utilities.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/03/24/simple-matrix-vector-permutation-utilities.aspx"&gt;Vector and matrix utilities&lt;/A&gt;.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;&lt;A href="http://blogs.msdn.com/natbr/archive/2009/07/12/quadratic-assignment-problems-branching.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/07/12/quadratic-assignment-problems-branching.aspx"&gt;Branching&lt;/A&gt;.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;&lt;A href="http://blogs.msdn.com/natbr/archive/2009/07/19/quadratic-assignment-problems-strong-and-weak-branching.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/07/19/quadratic-assignment-problems-strong-and-weak-branching.aspx"&gt;Strong and weak branching&lt;/A&gt;.&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;In my next post I will fill in a couple of the gaps, and then I will re-post all of the code.&amp;nbsp; Then we'll think about what we can actually do with a QAP solver!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9850185" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/QAP/default.aspx">QAP</category><category domain="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx">combinatorial optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx">operations research</category></item><item><title>Quadratic Assignment Problems: strong and weak branching</title><link>http://blogs.msdn.com/natbr/archive/2009/07/19/quadratic-assignment-problems-strong-and-weak-branching.aspx</link><pubDate>Mon, 20 Jul 2009 05:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9840714</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9840714.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9840714</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9840714</wfw:comment><description>&lt;P&gt;Let's pick up where we left off &lt;A href="http://blogs.msdn.com/natbr/archive/2009/07/12/quadratic-assignment-problems-branching.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/07/12/quadratic-assignment-problems-branching.aspx"&gt;last time&lt;/A&gt; and write a score-based Branch delegate.&amp;nbsp; It will be used as the basis for&amp;nbsp;both of our "real"&amp;nbsp;branching functions.&amp;nbsp; &lt;/P&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchingDecision&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; BranchCore(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchAndBoundNode&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; node, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; bound, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[][] S) {&lt;BR&gt;&amp;nbsp; RowColumnSums(S, node.Size);&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; rowVal, colVal;&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; rowBest = _rowSum.ArgMax(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;out&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; rowVal);&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; colBest = _colSum.ArgMax(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;out&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; colVal);&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;if&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; (rowVal &amp;gt; colVal) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchingDecision&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;true&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;, rowBest);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;else&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchingDecision&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;false&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;, colBest);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; RowColumnSums(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[][] U, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; size) {&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;if&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; (_rowSum == &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rowSum = &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[_qap.Size];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _colSum = &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[_qap.Size];&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; _rowSum.ConstantFill(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;Double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;.MinValue);&lt;BR&gt;&amp;nbsp; _colSum.ConstantFill(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;Double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;.MinValue);&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;for&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; (&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; i = 0; i &amp;lt; size; i++) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;for&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; (&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; j = 0; j &amp;lt; size; j++) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rowSum[i] += U[i][j];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _colSum[j] += U[i][j];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;If we can create a reasonable score matrix and pass it into BranchCore, then we've got something.&amp;nbsp; Two common techniques for QAP are:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Weak branching.&lt;/STRONG&gt;&amp;nbsp; Let S_ij be the reduced cost U_ij that we got from computing the lower bound.&amp;nbsp; (U_ij is a lower bound on the amount that the bound on the subproblem will increase.&amp;nbsp; So large U_ij means the subproblem will be a lot easier.)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Strong branching.&amp;nbsp; &lt;/STRONG&gt;Let S_ij be the bound for subproblem ij.&amp;nbsp; The bigger the bound, the easier the subproblem.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Weak branching is trivial to implement for the &lt;A href="http://www.seas.upenn.edu/qaplib/codes.html" target=_blank mce_href="http://www.seas.upenn.edu/qaplib/codes.html"&gt;Gilmore-Lawler&lt;/A&gt; (or&amp;nbsp;GLB) bound.&amp;nbsp; &lt;A href="http://blogs.msdn.com/natbr/archive/2008/07/10/quadratic-assignment-problems-bounds.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2008/07/10/quadratic-assignment-problems-bounds.aspx"&gt;As I mentioned a long time ago&lt;/A&gt;, the reduced cost matrix essentially comes for free.&lt;/P&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchingDecision&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; WeakBranch(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchAndBoundNode&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; node, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; bound, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[][] U) {&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; BranchCore(node, bound, U);&lt;BR&gt;}&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;For strong branching we need to compute bounds for each subproblem.&amp;nbsp; We overwrite the U matrix and pass it into BranchCore.&amp;nbsp; Since the U matrix is used to fathom subproblems later on in the code, we subtract the parent bound from the bound of each subproblem.&lt;/P&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchingDecision&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; StrongBranch(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchAndBoundNode&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; node, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; bound, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[][] U) {&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;Qap&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; r = &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;Qap&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;(node.Size - 1);&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[][] Ur = &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;MatrixUtilities&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;.NewMatrix(node.Size - 1, node.Size - 1);&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;for&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; (&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; i = 0; i &amp;lt; node.Size; i++) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;for&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; (&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; j = 0; j &amp;lt; node.Size; j++) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;Qap&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;.Reduce(node.Qap, r, i, j);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; U[i][j] = &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;GLB&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;.Bound(r, Ur) - bound;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; BranchCore(node, bound, U);&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;Strong branching in general produces better guesses that weak branching.&amp;nbsp; However, it comes at a computational cost.&amp;nbsp; Therefore I want to introduce one last complication…er…feature.&amp;nbsp; Since strong branching is smarter but more costly, we should only use it where it is most needed.&amp;nbsp; I want to have a set of rules that governs when to use strong or weak branching.&amp;nbsp; Branching decisions are most important at the top of the tree, or on nodes where the bound sucks.&amp;nbsp; We can measure the suckiness of the bound for a node by computing the relative gap:&amp;nbsp; the ratio of the gap between the bound and the incumbent solution, and the corresponding gap at the root.&amp;nbsp;&amp;nbsp; So our branching rule data structure will have Depth and Gap properties, as well as properties that store the Branch delegate information.&lt;/P&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;A description of a branching rule: when and how.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;class&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchingRule&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; {&lt;BR&gt;&lt;FONT color=#808080&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;The ID for this rule.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; Index { &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; }&lt;BR&gt;&lt;FONT color=#808080&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;Maximum depth for which the rule applies.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; Depth { &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; }&lt;BR&gt;&lt;FONT color=#808080&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;Maximum relative gap for&amp;nbsp;which the rule applies.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; Gap { &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; }&lt;BR&gt;&lt;FONT color=#808080&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;Strong or Weak.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchType&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; Type { &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; }&lt;BR&gt;&lt;FONT color=#808080&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;StrongBranch() or WeakBranch().&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;internal&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;Branch&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; Rule { &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; BranchingRule(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; index, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; gap, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; depth, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchType&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; type) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Index = index;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Depth = depth;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Gap = gap;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type = type;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; &lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;override&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; ToString() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;"Depth = "&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; + Depth + &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;", Gap = "&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; + Gap + &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;&lt;FONT color=#a31515 size=2 face=Consolas&gt;", Type = "&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; + Type.ToString();&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;We will have an array of BranchingRule called _branchingRule.&amp;nbsp; Given a node, we will select the first rule in the array whose depth is larger than the node depth, and whose gap is larger than the node gap.&lt;/P&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;Branch&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; SelectBranchingRule(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchAndBoundNode&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; node) {&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; gap = _results.RelativeGap(node.LowerBound);&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchingRule&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; criterion = _branchingRules.First(entry =&amp;gt; (node.Level &amp;lt;= entry.Depth) &amp;amp;&amp;amp; (gap &amp;gt;= entry.Gap));&lt;BR&gt;&amp;nbsp; node.RuleIndex = criterion.Index;&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; criterion.Rule;&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;I am cheating here because I have not defined the local variable _results.&amp;nbsp; We'll get to that in a few posts.&amp;nbsp; For now, just assume that RelativeGap is defined as I described above: (Objective - bound) / (Objective - RootBound).&amp;nbsp; &lt;/P&gt;
&lt;P&gt;At long last, that covers branching.&amp;nbsp; There are many variations, but they are essentially variations of strong or weak branching.&amp;nbsp; At this point we only have two more main topics to cover: what to do when you get to the bottom of the tree, and how do you capture and update results.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9840714" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/QAP/default.aspx">QAP</category><category domain="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx">combinatorial optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx">operations research</category></item><item><title>Quadratic assignment problems: branching</title><link>http://blogs.msdn.com/natbr/archive/2009/07/12/quadratic-assignment-problems-branching.aspx</link><pubDate>Mon, 13 Jul 2009 02:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9830717</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9830717.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9830717</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9830717</wfw:comment><description>&lt;P&gt;(This is part of a long-running series on quadratic assignment problems in C#.&amp;nbsp; &lt;A href="http://blogs.msdn.com/natbr/archive/2009/03/23/branch-and-bound-algorithms-for-qap.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/03/23/branch-and-bound-algorithms-for-qap.aspx"&gt;Click here to&amp;nbsp;catch up.&lt;/A&gt;)&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/natbr/archive/2009/03/23/branch-and-bound-algorithms-for-qap.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/03/23/branch-and-bound-algorithms-for-qap.aspx"&gt;Branching&lt;/A&gt; means to divide the search space represented by a node into subnodes.&amp;nbsp; QAP is about making assignments of facilities to locations, so two possible approaches come to mind:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Branch into two subproblems: one where an assignment i -&amp;gt; j is allowed, and another where it is disallowed.&lt;/LI&gt;
&lt;LI&gt;Pick a facility and try assigning it to all possible locations, creating N subproblems.&amp;nbsp; (Or pick a location and assign all facilities to it…)&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;The second approach, called &lt;STRONG&gt;polytomic branching&lt;/STRONG&gt;, turns out to be more effective.&amp;nbsp; The problem with the first ("single assignment branching") is that the subproblems aren't that much easier than the parent problem.&amp;nbsp; You'll have to branch a whole bunch of times before you are able to determine anything.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;We still need to decide whether to fix a facility ("row branching") or a location ("column branching").&amp;nbsp; And after that we need to figure out which particular facility or location is best.&amp;nbsp; At this point you may be wondering, "does it even matter?"&amp;nbsp; The answer is that, yes, branching decisions are earth shatteringly important.&amp;nbsp; Where's what I mean: if you make bad branching choices it could take a thousand times longer to solve the problem, or more!&amp;nbsp; This is part of the reason why QAP (and branch-and-bound) are so interesting.&amp;nbsp; Bad branching decisions lead to subproblems that are just about as hard as the original problem.&amp;nbsp; &lt;A href="http://www.youtube.com/watch?v=LD8HDta7Z_4" target=_blank mce_href="http://www.youtube.com/watch?v=LD8HDta7Z_4"&gt;It's kind of like this.&lt;/A&gt;&amp;nbsp; Here is a data structure that represents the results of a polytomic branching decision.&lt;/P&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;A branching decision, the result of applying a branching rule.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;internal&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;class&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchingDecision&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; {&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;If true, enumerate over all unassigned rows.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&amp;nbsp; public&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;bool&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; IsRowBranch { &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; }&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;The row or column index.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&amp;nbsp; public&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; Index { &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;set&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;; }&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;Create a new instance.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;nbsp; ///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; BranchingDecision(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;bool&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; isRowBranch, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; index) {&lt;BR&gt;&amp;nbsp;&amp;nbsp; IsRowBranch = isRowBranch;&lt;BR&gt;&amp;nbsp;&amp;nbsp; Index = index;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;Ultimately we want to write methods that produce BranchingDecisions.&amp;nbsp; The following delegate represents such a method (we will write two methods in the next blog post):&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;summary&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;Makes a branching decision.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;///&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt;&lt;FONT color=#008000 size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&lt;FONT color=#808080 size=2 face=Consolas&gt;&amp;lt;/summary&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;internal&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;delegate&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchingDecision&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;Branch&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;&lt;FONT color=#2b91af size=2 face=Consolas&gt;BranchAndBoundNode&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; node, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt; bound, &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;&lt;FONT color=#0000ff size=2 face=Consolas&gt;double&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2 face=Consolas&gt;&lt;FONT size=2 face=Consolas&gt;[][] U);&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;If you accept the claim that branching choices make a big difference, then it is&amp;nbsp;clear that we want to&amp;nbsp;branch&amp;nbsp;so we get the&amp;nbsp;easiest subproblems possible.&amp;nbsp; That is, nodes that will be processed by the branch-and-bound algorithm as quickly as possible.&amp;nbsp; We don't know how to measure that directly (why?), so we have to guess.&amp;nbsp; A general framework for polytomic branching is to compute a score for each of the N^2 subproblems, and store it in a matrix.&amp;nbsp; S_ij is the score for the subproblem created by fixing facility i to location j.&amp;nbsp; Then compute the row and column sums of S, and branch on the row or the column with maximum sum.&amp;nbsp; Making a branching choice reduces to computing scores on subproblems.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The next step will be to write methods that compute scores and return BranchingDecisions.&amp;nbsp; We'll look at two common ways to do that next time.&amp;nbsp; We're about two or three posts away from having a pretty decent branch-and-bound solver for QAP.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9830717" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/QAP/default.aspx">QAP</category><category domain="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx">combinatorial optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category></item><item><title>Solver Foundation LINQ to SQL example</title><link>http://blogs.msdn.com/natbr/archive/2009/06/02/solver-foundation-linq-to-sql-example.aspx</link><pubDate>Tue, 02 Jun 2009 17:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9685593</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9685593.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9685593</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9685593</wfw:comment><description>&lt;P&gt;Erwin, a modeling consultant and top Solver Foundation user, &lt;A href="http://yetanothermathprogrammingconsultant.blogspot.com/2009/05/ms-solver-foundation-data-binding.html" target=_blank mce_href="http://yetanothermathprogrammingconsultant.blogspot.com/2009/05/ms-solver-foundation-data-binding.html"&gt;encountered some problems trying to do two-way data binding&lt;/A&gt; using DataTable objects.&amp;nbsp; There are more details on &lt;A href="http://code.msdn.microsoft.com/solverfoundation/Thread/View.aspx?ThreadId=1812" target=_blank mce_href="http://code.msdn.microsoft.com/solverfoundation/Thread/View.aspx?ThreadId=1812"&gt;this discussion thread&lt;/A&gt;.&amp;nbsp; Ross, a member of the Solver Foundation team, was kind enough to code up a workaround for Erwin's example.&amp;nbsp; In addition to this CS file, you will need to create a new DBML file called SampleDataContext, &lt;A href="http://blogs.msdn.com/natbr/archive/2009/05/05/creating-parameterized-solver-foundation-models-using-linq-to-sql.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/05/05/creating-parameterized-solver-foundation-models-using-linq-to-sql.aspx"&gt;as I described in a previous post&lt;/A&gt;.&lt;/P&gt;&lt;PRE&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Data.OleDb;
using System.Data.Linq;
using System.Text;
using Microsoft.SolverFoundation.Services;
using System.IO;
 
namespace OML1
{
    class Test
    {
        static void Main(string[] args)
        {
            Test t = new Test();
            t.Solve();
        }
 
        // Holds the OML model
        string strModel = @"Model[
              Parameters[Sets,I],
              Parameters[Reals,p[I]],
 
              Decisions[Reals[0,Infinity],x[I]],
 
              Constraints[
                 Foreach[{i,I}, x[i]==p[i]]
              ]
           ]";
 
 
        //  SFS
        SolverContext context;
        SampleDataContext data;
 
 
        //  Constructor
        public Test()
        {
            context = SolverContext.GetContext();
            data = new SampleDataContext("Data Source=Sql_server_name;Initial Catalog=DataPartitionAllocation20_5;Integrated Security=True");
            context.DataSource = data;
        }
 
 
        // Solve the problem
        public void Solve()
        {
            context.LoadModel(FileFormat.OML, new StringReader(strModel));
 
            Parameter p = context.CurrentModel.Parameters.First(q =&amp;gt; q.Name == "p");
            p.SetBinding(data.P, "value", new string[] { "index" });
 
            Decision x = context.CurrentModel.Decisions.First(d =&amp;gt; d.Name == "x");
            x.SetBinding(data.X, "value", new string[] { "index" }); 
 
            Solution solution = context.Solve();
            Console.Write("{0}", solution.GetReport());
 
            context.PropagateDecisions();
 
        }
 
    }
 
}
&lt;/PRE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9685593" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx">Solver Foundation</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/natbr/archive/tags/OML/default.aspx">OML</category><category domain="http://blogs.msdn.com/natbr/archive/tags/SQL/default.aspx">SQL</category></item><item><title>Solver Foundation TSP Part II: Directives, Solver Plugins, Model Libraries</title><link>http://blogs.msdn.com/natbr/archive/2009/05/07/solver-foundation-tsp-part-ii-directives-solver-plugins-model-libraries.aspx</link><pubDate>Fri, 08 May 2009 06:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9595777</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9595777.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9595777</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9595777</wfw:comment><description>Here is my as-promised "part 2" to my &lt;A href="http://blogs.msdn.com/natbr/archive/2009/04/27/solving-traveling-salesman-problems-using-solver-foundation.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/04/27/solving-traveling-salesman-problems-using-solver-foundation.aspx"&gt;traveling salesman sample&lt;/A&gt;. My goal is not to try and do any "production level" modeling, but instead "point the way" by highlighting different aspects of Solver Foundation's architecture. This time I want to talk about &lt;STRONG&gt;directives&lt;/STRONG&gt;, &lt;STRONG&gt;plug-in solvers&lt;/STRONG&gt;, and &lt;STRONG&gt;model reusability&lt;/STRONG&gt;. The Solver Foundation architecture provides the ability to plug-in other solvers to handle one or more problem types. As of version 1.1, the Gurobi solver is Solver Foundation's default MIP (mixed integer programming)&amp;nbsp;solver. &lt;A href="http://www.gurobi.com/" mce_href="http://www.gurobi.com"&gt;Gurobi&lt;/A&gt; is a high-performance solver which is capable of taking on industrial strength problems, so my piddling little TSP example is no match for it. Gurobi has a number of parameters that can be set to tune solver performance - you set them by means of Directives. First, let's modify our code to turn on logging. Change the context.Solve() call to: &lt;PRE&gt;      GurobiDirective gurobiDirective = new GurobiDirective();
      gurobiDirective.OutputFlag = true;
      Solution solution = context.Solve(gurobiDirective);
&lt;/PRE&gt;Each plug-in solver also defines its own directives - therefore the full power and flexibility of plug-in solvers are available to you as a programmer. In this case I have just flipped on the logging bit - here's what I see. &lt;PRE&gt;Optimize a model with 185 Rows, 380 Columns and 1199 NonZeroes
Presolve removed 1 rows and 185 columns
Presolve time: 0.30s
Presolved: 184 Rows, 195 Columns, 832 Nonzeros
Objective GCD is 1

Root relaxation: objective 2.783286e+03, 36 iterations, 0.02 seconds

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

     0     0  2783.2857    0   14          -  2783.2857     -      -    0s
     0     0  3006.1964    0   29          -  3006.1964     -      -    0s
     0     0  3006.1964    0   29          -  3006.1964     -      -    0s
     0     0  3006.1964    0   25          -  3006.1964     -      -    0s
     0     0  3006.1964    0   25          -  3006.1964     -      -    0s
H    0     0                       6029.0000  3006.1964  50.1%     -    0s
     0     0  3006.1964    0   25  6029.0000  3006.1964  50.1%     -    0s
H    0     2                       3805.0000  3006.1964  21.0%     -    0s
     0     2  3006.1964    0   25  3805.0000  3006.1964  21.0%     -    0s
*   75    54              29       3644.0000  3077.0000  15.6%   8.2    0s
*  129    80              27       3381.0000  3077.0000  8.99%   8.7    0s
*  158    62              30       3323.0000  3077.0000  7.40%   8.1    0s

Cutting planes:
  Learned: 3
  Gomory: 1
  MIR: 3

Explored 1231 nodes (5693 simplex iterations) in 0.69 seconds
Thread count was 2 (of 2 available processors)

Optimal solution found (tolerance 1.00e-04)
Best objective 3.3230000000e+03, best bound 3.3230000000e+03, gap 0.0000%
&lt;/PRE&gt;For large models it is sometimes useful to tweak the solver options for performance. For example, if I wanted to spend a slightly larger amount of time doing MIP heuristics, and I wanted to eliminate presolve, then I can set those options easily: &lt;PRE&gt;      gurobiDirective.Heuristics = 0.1;
      gurobiDirective.Presolve = PresolveLevel.None;
&lt;/PRE&gt;
&lt;P&gt;There is a full reference in the Gurobi Solver Programming Primer that ships with Solver Foundation. My point is that you do not get a "least common denominator" solution - you get all the bells and whistles. &lt;/P&gt;
&lt;P&gt;Gurobi is just one example - there are a wide range of plug-ins available, covering most of the popular LP and MIP solvers - check out &lt;A href="http://www.solverfoundation.com/" mce_href="http://www.solverfoundation.com"&gt;solverfoundation.com&lt;/A&gt; for the full list. To use a plug-in solver, you need to: 1) install the solver (duh), 2) change your exe.config or web.config to point to the solver. No code changes are required. You can find additional documentation on the default MIP directives and the third-party Solver configuration in the SFS Programming Primer. &lt;/P&gt;
&lt;P&gt;Last thing - modern programming languages like C# are cool because they promote reusability and maintainability. Don't forget about that when you are writing SFS code. It's common for models in a particular vertical (say, finance or transportation) to have common "blocks" of goals or constraints that are re-used over and over again. It's pretty easy to build reusable model libraries using extension methods. For example, take the assignment constraints in my TSP example. I could factor them out: &lt;/P&gt;&lt;PRE&gt;  public static class ModelingExtensions {
    public static void AssignmentConstraintsNoDiag(this Model model, Set s, Decision assign) {
      model.AddConstraint("A1", Model.ForEach(s, i =&amp;gt; Model.Sum(Model.ForEachWhere(s, j =&amp;gt; assign[i, j], j =&amp;gt; i != j)) == 1));
      model.AddConstraint("A2", Model.ForEach(s, j =&amp;gt; Model.Sum(Model.ForEachWhere(s, i =&amp;gt; assign[i, j], i =&amp;gt; i != j)) == 1));
    }
  }
&lt;/PRE&gt;Now I can just say model.AssignmentConstraintsNoDiag(city, assign). I could add other variations inside of ModelingExtensions as well. I think this aspect of Solver Foundation has not gotten enough attention - maybe because it doesn't make for a cool demo! &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9595777" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx">combinatorial optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx">Solver Foundation</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/INFORMS/default.aspx">INFORMS</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Gurobi/default.aspx">Gurobi</category></item><item><title>Creating parameterized Solver Foundation models using LINQ to SQL</title><link>http://blogs.msdn.com/natbr/archive/2009/05/05/creating-parameterized-solver-foundation-models-using-linq-to-sql.aspx</link><pubDate>Tue, 05 May 2009 23:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9589626</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9589626.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9589626</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9589626</wfw:comment><description>&lt;P&gt;&lt;A href="http://code.msdn.microsoft.com/solverfoundation/Thread/View.aspx?ThreadId=1665" mce_href="http://code.msdn.microsoft.com/solverfoundation/Thread/View.aspx?ThreadId=1665"&gt;On the Solver Foundation MSDN forum&lt;/A&gt; there was a question about how to read model data from a DB and use it within a Solver Foundation model.&amp;nbsp; In this post I will extend my production planning sample to use LINQ to SQL.&amp;nbsp; To follow along at home you will need to have a recent version of SQL Server installed locally, and some basic knowledge of how to create SQL tables.&amp;nbsp; You should also have compiled and run the code from my &lt;A href="http://blogs.msdn.com/natbr/archive/2009/04/24/modeling-a-production-planning-problem-using-solver-foundation.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/04/24/modeling-a-production-planning-problem-using-solver-foundation.aspx"&gt;previous post&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 1: Create and populate the DB&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The first step is to create tables corresponding to the entities in my model.&amp;nbsp; I created a very simple DB with three tables: Countries, Products, and Yields.&amp;nbsp; The Yields table has foreign key constraints to the Countries and Products tables.&amp;nbsp; Here is a diagram:&lt;/P&gt;
&lt;P&gt;&lt;IMG title="Petrochem Entities" alt="Petrochem Entities" src="http://blogs.msdn.com/photos/nathan_brixius/images/9589627/original.aspx" mce_src="http://blogs.msdn.com/photos/nathan_brixius/images/9589627/original.aspx"&gt;&lt;/P&gt;
&lt;P&gt;To populate the DB I just wrote a script that inserts my problem data, and ran itin SQL Management Studio.&amp;nbsp; Here's the script (and forgive my SQL):&lt;/P&gt;&lt;PRE&gt;GO 

DELETE FROM Yields
DELETE FROM Products
DELETE FROM Countries
GO

INSERT INTO Countries (Id, Name, Limit, Cost)
VALUES (0, 'SA', 9000, 20)

INSERT INTO Countries (Id, Name, Limit, Cost)
VALUES (1, 'VZ', 6000, 15)

GO

INSERT INTO Products (Id, Name, Demand)
VALUES (0, 'Gas', 1900)

INSERT INTO Products (Id, Name, Demand)
VALUES (1, 'Jet Fuel', 1500)

INSERT INTO Products (Id, Name, Demand)
VALUES (2, 'Lubricant', 500)

GO

INSERT INTO Yields (CountryId, ProductId, Value)
VALUES (0, 0, 0.3)
INSERT INTO Yields (CountryId, ProductId, Value)
VALUES (1, 0, 0.4)

INSERT INTO Yields (CountryId, ProductId, Value)
VALUES (0, 1, 0.4)
INSERT INTO Yields (CountryId, ProductId, Value)
VALUES (1, 1, 0.2)

INSERT INTO Yields (CountryId, ProductId, Value)
VALUES (0, 2, 0.2)
INSERT INTO Yields (CountryId, ProductId, Value)
VALUES (1, 2, 0.3)
&lt;/PRE&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 2: Create Entity and DataContext classes in Visual Studio&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;&lt;A href="http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx" mce_href="http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx"&gt;Scott Guthrie's blog&lt;/A&gt; (and the MSDN docs) show you exactly how to do this:&amp;nbsp; &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Add a new "Linq to SQL file" to your project called Petrochem.dbml.&lt;/LI&gt;
&lt;LI&gt;Bring up the Server Explorer window, connect to your database and drag the tables into the dbml window.&amp;nbsp; Visual Studio will automatically create a Datacontext class (mine is called PetrochemDataContext) and an entity class for each table that you include.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 257px; HEIGHT: 180px" title="Petrochem DB" alt="Petrochem DB" src="http://blogs.msdn.com/photos/nathan_brixius/images/9589628/original.aspx" width=257 height=180 mce_src="http://blogs.msdn.com/photos/nathan_brixius/images/9589628/original.aspx"&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 3: Modify Solver Foundation Services data binding code&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This is in fact very easy because Solver Foundation Services was designed to work well with LINQ.&amp;nbsp; Take the PetrochemDataBinding sample from last time, and change the SetBinding statements to work with the PetrochemDataContext class instead of a hardcoded DataSet.&amp;nbsp; The code is almost identical:&lt;/P&gt;&lt;PRE&gt;  private static void PetrochemLinqDataBinding() {
      SolverContext context = SolverContext.GetContext();
      context.ClearModel();
      Model model = context.CreateModel();

      PetrochemDataContext db = new PetrochemDataContext();

      Set products = new Set(Domain.Any, "products");
      Set countries = new Set(Domain.Any, "countries");

      Parameter demand = new Parameter(Domain.Real, "demand", products);
      demand.SetBinding(db.Products, "Demand", "Id");

      Parameter yield = new Parameter(Domain.Real, "yield", products, countries);
      yield.SetBinding(db.Yields, "Value", "ProductId", "CountryId");

      Parameter limit = new Parameter(Domain.Real, "limit", countries);
      limit.SetBinding(db.Countries, "Limit", "Id");

      Parameter cost = new Parameter(Domain.Real, "cost", countries);
      cost.SetBinding(db.Countries, "Cost", "Id");

      model.AddParameters(demand, yield, limit, cost);

      Decision produce = new Decision(Domain.RealNonnegative, "produce", countries);
      model.AddDecision(produce);

      model.AddGoal("goal", GoalKind.Minimize, Model.Sum(Model.ForEach(countries, c =&amp;gt; cost[c] * produce[c])));

      model.AddConstraint("Demand",
        Model.ForEach(products, p =&amp;gt; Model.Sum(Model.ForEach(countries, c =&amp;gt; yield[p, c] * produce[c])) &amp;gt;= demand[p])
        );

      model.AddConstraint("Production limit",
        Model.ForEach(countries, c =&amp;gt; produce[c] &amp;lt;= limit[c])
        );

      Solution solution = context.Solve(new SimplexDirective());
      Report report = solution.GetReport();
      Console.WriteLine(report);
    }
&lt;/PRE&gt;
&lt;P&gt;That's all there is to it!&amp;nbsp; Note that instead of passing the entire collection (e.g. db.Countries) you could easily use LINQ statements or stored procedures, or whatever you like.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9589626" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx">Solver Foundation</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/natbr/archive/tags/OML/default.aspx">OML</category><category domain="http://blogs.msdn.com/natbr/archive/tags/SQL/default.aspx">SQL</category></item><item><title>Solving traveling salesman problems using Solver Foundation</title><link>http://blogs.msdn.com/natbr/archive/2009/04/27/solving-traveling-salesman-problems-using-solver-foundation.aspx</link><pubDate>Mon, 27 Apr 2009 18:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9571061</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9571061.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9571061</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9571061</wfw:comment><description>&lt;P&gt;Here's an example that I walked through during yesterday's INFORMS session.&amp;nbsp; Erwin has &lt;A href="http://yetanothermathprogrammingconsultant.blogspot.com/2009/03/tsp-in-oml-ms-solver-foundation.html" mce_href="http://yetanothermathprogrammingconsultant.blogspot.com/2009/03/tsp-in-oml-ms-solver-foundation.html"&gt;two&lt;/A&gt; &lt;A href="http://yetanothermathprogrammingconsultant.blogspot.com/2009/02/tsp-powerset-formulation.html" mce_href="http://yetanothermathprogrammingconsultant.blogspot.com/2009/02/tsp-powerset-formulation.html"&gt;blog postings&lt;/A&gt; about Solver Foundation and the traveling salesman problem, but I want to throw in my two cents because I want to emphasize a couple of points:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;By combining C# and Solver Foundation Services it is possible to express complex models clearly and succinctly.&lt;/LI&gt;
&lt;LI&gt;It is very easy to build powerful, reusable model libraries using C# and Solver Foundation Services.&lt;/LI&gt;
&lt;LI&gt;Solver Foundation Services code can be used in many different application environments (ASP.Net, silverlight, DB, command line apps, WPF, …) with minimal changes.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;The traveling salesman problem is a classical problem in computer science, and you should bow your head in shame if you don't know about it (and turn in your conference badge if you happen to be in Phoenix).&amp;nbsp; A salesperson needs to make a tour of a number of cities.&amp;nbsp; The restrictions are that she wants to visit each city once and only once, and she wants to minimize the distance travelled.&amp;nbsp; This is perhaps &lt;STRONG&gt;the&lt;/STRONG&gt; definitive example of an NP-hard problem.&lt;/P&gt;
&lt;P&gt;TSP can be solved using mixed integer programming - optimizing a linear goal with linear constraints, where some of the decision variables are integer.&amp;nbsp; In this first post I will show how to formulate and solve a TSP model using Solver Foundation Services.&amp;nbsp; In my second post I will show how to use the Gurobi MIP solver using SFS.&amp;nbsp;&amp;nbsp; There are many different ways to model the TSP - &lt;A href="http://archive.ite.journal.informs.org/Vol7No1/LeeRaffensperger/" mce_href="http://archive.ite.journal.informs.org/Vol7No1/LeeRaffensperger/"&gt;here&lt;/A&gt; is a nice introduction.&amp;nbsp; My goal is to provide a clear, complete example - not build a "production level" TSP model, so I am going to choose a model formulation that dates back to 1960!&amp;nbsp; First, I need to establish a couple of building blocks that will help me construct the data for the model.&amp;nbsp; We need to know the distances between each pair of cities.&amp;nbsp; Typically we are provided the coordinates of the cities and need to derive the distances.&amp;nbsp; So I will introduce a Coordinate class that contains properties for the (x, y) coordinates, and properties to convert to latitude and longitude.&amp;nbsp; Finally, a method that computes the distance between points.&lt;/P&gt;&lt;PRE&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SolverFoundation.Services;
using SolverFoundation.Plugin.Gurobi;

namespace Microsoft.SolverFoundation.Samples.TravelingSalesman {
  class Program {
    // TSP coordinate.
    public class Coordinate {
      public int Name { get; set; }

      // X-coordinate (from TSPLIB)
      public double X { get; set; }

      // Y-coordinate (from TSPLIB)
      public double Y { get; set; }

      public Coordinate(int name, double x, double y) {
        Name = name;
        X = x;
        Y = y;
      }

      // Latitude in radians.
      public double Latitude {
        get { return Math.PI * (Math.Truncate(X) + 5 * (X - Math.Truncate(X)) / 3) / 180; }
      }

      // Longitude in radians.
      public double Longitude {
        get { return Math.PI * (Math.Truncate(Y) + 5 * (Y - Math.Truncate(Y)) / 3) / 180; }
      }

      // Geographic distance between two points (as an integer).
      public int Distance(Coordinate p) {
        double q1 = Math.Cos(Longitude - p.Longitude);
        double q2 = Math.Cos(Latitude - p.Latitude);
        double q3 = Math.Cos(Latitude + p.Latitude);
        // There may rounding difficulties her if the points are close together...just sayin'.
        return (int)(6378.388 * Math.Acos(0.5 * ((1 + q1) * q2 - (1 - q1) * q3)) + 1);
      }
    }

    // TSP city-city arc.
    // &lt;/SUMMARY&gt;
    public class Arc {
      public int City1 { get; set; }
      public int City2 { get; set; }
      public double Distance { get; set; }
    }

    // Burma14 from TSPLIB. Optimal tour = 3323.
    private static Coordinate[] data = new Coordinate[] {
      new Coordinate(0, 16.47, 96.10),
      new Coordinate(1, 16.47, 94.44),
      new Coordinate(2, 20.09, 92.54),
      new Coordinate(3, 22.39, 93.37),
      new Coordinate(4, 25.23, 97.24),
      new Coordinate(5, 22.00, 96.05),
      new Coordinate(6, 20.47, 97.02),
      new Coordinate(7, 17.20, 96.29),
      new Coordinate(8, 16.30, 97.38),
      new Coordinate(9, 14.05, 98.12),
      new Coordinate(10, 16.53, 97.38),
      new Coordinate(11, 21.52, 95.59),
      new Coordinate(12, 19.41, 97.13),
      new Coordinate(13, 20.09, 94.55)
    };
&lt;/PRE&gt;
&lt;P&gt;(The data for this 14-city problem comes from the &lt;A href="http://www.iwr.uni-heidelberg.de/groups/comopt/software/TSPLIB95/" mce_href="http://www.iwr.uni-heidelberg.de/groups/comopt/software/TSPLIB95/"&gt;TSPLIB&lt;/A&gt; library). If you've been following my blog you know that the building blocks of a Solver Foundation model are: sets, parameters, decisions, goals, and constraints. I am going to implement a simple formulation that is centered around&amp;nbsp;the following (indexed) decisions:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Assign[i,j]: this is equal to 1 if the optimal tour contains a trip (or arc) from city i to city j.&lt;/LI&gt;
&lt;LI&gt;Rank[i]: this is equal to the number of cities visited after arriving at city i.&amp;nbsp;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;We have one parameter in our model:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Distance[I,j]: the distance from city i to city j.&amp;nbsp;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;With that in mind, here's the model.&amp;nbsp; Explanation of the goals and constraints follow.&lt;/P&gt;&lt;PRE&gt;    static void Main(string[] args) {
      SolverContext context = SolverContext.GetContext();
      Model model = context.CreateModel();

      // ------------
      // Parameters
      Set city = new Set(Domain.IntegerNonnegative, "city");
      Parameter dist = new Parameter(Domain.Real, "dist", city, city);
      var arcs = from p1 in data
                 from p2 in data
                 select new Arc { City1 = p1.Name, City2 = p2.Name, Distance = p1.Distance(p2) };
      dist.SetBinding(arcs, "Distance", "City1", "City2");
      model.AddParameters(dist);

      // ------------
      // Decisions
      Decision assign = new Decision(Domain.IntegerRange(0, 1), "assign", city, city);
      Decision rank = new Decision(Domain.RealNonnegative, "rank", city);
      model.AddDecisions(assign, rank);

      // ------------
      // Goal: minimize the length of the tour.
      Goal goal = model.AddGoal("TourLength", GoalKind.Minimize,
        Model.Sum(Model.ForEach(city, i =&amp;gt; Model.ForEachWhere(city, j =&amp;gt; dist[i, j] * assign[i, j], j =&amp;gt; i != j))));

      // ------------
      // Enter and leave each city only once.
      int N = data.Length;
      model.AddConstraint("assign 1",
        Model.ForEach(city, i =&amp;gt; Model.Sum(Model.ForEachWhere(city, j =&amp;gt; assign[i, j],
          j =&amp;gt; i != j)) == 1));
      model.AddConstraint("assign 2",
        Model.ForEach(city, j =&amp;gt; Model.Sum(Model.ForEachWhere(city, i =&amp;gt; assign[i, j], i =&amp;gt; i != j)) == 1));
      model.AssignmentNoDiag(city, assign);

      // Forbid subtours (Miller, Tucker, Zemlin - 1960...)
      model.AddConstraint("no subtours",
        Model.ForEach(city,
          i =&amp;gt; Model.ForEachWhere(city,
            j =&amp;gt; rank[i] + 1 &amp;lt;= rank[j] + N * (1 - assign[i, j]),
            j =&amp;gt; Model.And(i != j, i &amp;gt;= 1, j &amp;gt;= 1)
          )
        )
      );

      Solution solution = context.Solve();

      // Retrieve solution information.
      Console.WriteLine("Cost = {0}", goal.ToDouble());
      Console.WriteLine("Tour:");
      var tour = from p in assign.GetValues() where (double)p[0] &amp;gt; 0.9 select p[2];
      foreach (var i in tour.ToArray()) {
        Console.Write(i + " -&amp;gt; ");
      }
      Console.WriteLine();
    }
  }
&lt;/PRE&gt;&lt;PRE style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;In my humble opinion, the "Parameter data =" line is an awesome example of the power of LINQ data binding in Solver Foundation.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;We generate the 2D matrix of distances using a single LINQ expression.  It would be incredibly easy to change the code to retrieve the coordinate data from a database (perhaps using a LINQ expression once again), a file, or even a user application.&lt;/PRE&gt;&lt;PRE style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;The goal is straightforward: minimize the distance traveled.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This is a product of the selected arcs and the distance matrix.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;We have two types of constraints:&lt;/PRE&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;PRE style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;&lt;SPAN style="FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;Assignment constraints: these ensure that we enter and leave each city only once.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;PRE style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;&lt;SPAN style="FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;Subtour constraints: these ensure that we do not have any subtours.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In a four city problem {A, B, C, D}, for example, we cannot have two cycles (A, B), (C, D).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;We need to have one tour that contains all the cities.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;PRE style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;The assignment constraints are easy using the ForEach and ForEachWhere operations.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I use ForEachWhere because I want to disallow arcs that enter and leave the same city - that doesn't make sense.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The subtour constraint is a little more complicated.   It relates the "assign" and "rank" decisions.  The key fact is that if there is an arc from city i to city j, rank[i] + 1 == j.  Of course, if the (i, j) arc is not part of the optimal tour then all bets are off.   Last note: notice that I can mix parameters, decisions, and C# variables in my expressions. &lt;/PRE&gt;&lt;PRE style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt; &lt;P style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;Once we solve the model we want to print out the cost, and the optimal tour.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Getting the cost is very easy using goal.ToDouble().&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;We can get the tour using either Assign or Rank.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I have chosen to use Assign because it gives me another opportunity to use LINQ.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;When you call GetValues() on a decision, you get arrays that contain the value along with the indexes for each decision.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In this case, the last entry in the array is the one we are interested in.  There are other ways to conveniently query decsision results, I'll save that for another time.&lt;/P&gt;&lt;P style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;P style="MARGIN: 0in; FONT-FAMILY: Calibri; FONT-SIZE: 11pt"&gt;The next post will show how we can use Solver Foundation's plug-in model to tune the behavior of the Gurobi MIP solver.&lt;/P&gt; &lt;/PRE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9571061" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx">combinatorial optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx">Solver Foundation</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/natbr/archive/tags/INFORMS/default.aspx">INFORMS</category></item><item><title>Modeling a production planning problem using Solver Foundation</title><link>http://blogs.msdn.com/natbr/archive/2009/04/24/modeling-a-production-planning-problem-using-solver-foundation.aspx</link><pubDate>Fri, 24 Apr 2009 23:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9567262</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9567262.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9567262</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9567262</wfw:comment><description>&lt;P&gt;In this post I am going to present two complete C# programs for modeling and solving a simple production problem using Solver Foundation. In this example we have two refineries (located in Saudi Arabia and Venzuela) that produce three products: gasoline, jet fuel, and lubricant. The goal is to minimize production costs, which depend on location. There is demand for each product which must be met. Finally, each production site has a limited production capacity. &lt;/P&gt;
&lt;P&gt;The code for the simple case&amp;nbsp;is below.&amp;nbsp;&amp;nbsp;Creating&amp;nbsp;a model amounts to adding the goals, decisions, and constraints using the appropriate Add method.&amp;nbsp; The signature for each is similar: the first argument is the name and the second argument is a term.&amp;nbsp; Terms are created by combining decisions or parameters using the usual operators, or by using static methods on the Model class (as we will see in our second example).&amp;nbsp; Finally, notice the call to SolverContext.Solve().&amp;nbsp; I have supplied a Directive that specifies that the Simplex solver should be used.&lt;/P&gt;&lt;PRE&gt;using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Microsoft.SolverFoundation.Services;

namespace Microsoft.SolverFoundation.Samples.Petrochem {
  class Program {
    static void Main(string[] args) {
      PetrochemSimple();
    }

    private static void PetrochemSimple() {
      SolverContext context = SolverContext.GetContext();
      context.ClearModel();
      Model model = context.CreateModel();

      Decision sa = new Decision(Domain.RealRange(0, 9000), "SA");
      Decision vz = new Decision(Domain.RealRange(0, 6000), "VZ");
      model.AddDecisions(sa, vz);

      model.AddGoal("goal", GoalKind.Minimize, 20 * sa + 15 * vz);

      model.AddConstraint("demand1", 0.3 * sa + 0.4 * vz &amp;gt;= 1900);
      model.AddConstraint("demand2", 0.4 * sa + 0.2 * vz &amp;gt;= 1500);
      model.AddConstraint("demand3", 0.2 * sa + 0.3 * vz &amp;gt;= 500);

      Solution solution = context.Solve(new SimplexDirective());
      Report report = solution.GetReport();
      Console.WriteLine(report);
    }
  }
&lt;/PRE&gt;
&lt;P&gt;Now let's reimplement the same example using data binding. Data binding is a powerful mechanism for creating large, maintainable models. Notice that in my first example, the numeric data such as the yields, the demands, and capacities were expressed directly in the terms. The first step in using Solver Foundation data binding is to lift these values into Parameters. It is often useful to create indexed parameters using Sets. In this example, there are two clearly defined Sets: the set of countries, and the set of products. In my example below I create a DataSet which contains the data for each of my parameters. (The GetData() method is just an example, it's not pretty but it is needed to complete the example.) Then I create a series of indexed parameters. For each of them I call the SetBinding method to associate the data with the parameter. In addition to the data, SetBinding also requires the caller to indicate which property specifies the values for the parameter. If the parameter is indexed, I also need to specify the parameters of the index properties. Since I am working with DataTables, these are simply column names. Notice that I could swap in any other data source that is enumerable - in particular LINQ works really well with Solver Foundation parameters. &lt;/P&gt;
&lt;P&gt;After the parameters are created, I define the decisions, goals, and constraints. Notice that there is only one decision - it is indexed. The Model.Sum and Model.Foreach operations allow me to define a series of constraints over one or more indexed sets in one single statement. This means that if I were to add more countries or products, my model definition would not change at all. &lt;/P&gt;&lt;PRE&gt;    private static void PetrochemDataBinding() {
      SolverContext context = SolverContext.GetContext();
      context.ClearModel(); 
      Model model = context.CreateModel();

      // Retrieve the problem data.
      DataSet data = GetData();

      Set products = new Set(Domain.Any, "products");
      Set countries = new Set(Domain.Any, "countries");
      
      Parameter demand = new Parameter(Domain.Real, "demand", products);
      demand.SetBinding(data.Tables["Demand"].AsEnumerable(), "Demand", "Product");

      Parameter yield = new Parameter(Domain.Real, "yield", products, countries);
      yield.SetBinding(data.Tables["Yield"].AsEnumerable(), "Yield", "Product", "Country");

      Parameter limit = new Parameter(Domain.Real, "limit", countries);
      limit.SetBinding(data.Tables["Limit"].AsEnumerable(), "Limit", "Country");

      Parameter cost = new Parameter(Domain.Real, "cost", countries);
      cost.SetBinding(data.Tables["Cost"].AsEnumerable(), "Cost", "Country");

      model.AddParameters(demand, yield, limit, cost);

      Decision produce = new Decision(Domain.RealNonnegative, "produce", countries);
      model.AddDecision(produce);

      model.AddGoal("goal", GoalKind.Minimize, Model.Sum(Model.ForEach(countries, c =&amp;gt; cost[c] * produce[c])));

      model.AddConstraint("Demand", 
        Model.ForEach(products, p =&amp;gt; Model.Sum(Model.ForEach(countries, c =&amp;gt; yield[p, c] * produce[c])) &amp;gt;= demand[p])
        );

      model.AddConstraint("Production limit",
        Model.ForEach(countries, c =&amp;gt; produce[c] &amp;lt;= limit[c])
        );

      Solution solution = context.Solve(new SimplexDirective());
      Report report = solution.GetReport();
      Console.WriteLine(report);
    }

    private static DataSet GetData() {
      string[] products = new string[] { "Gas", "Jet Fuel", "Lubricant" };
      string[] countries = new string[] { "SA", "VZ" };

      double[][] yield = new double[][] {
        new double[] { 0.3, 0.4 }, 
        new double[] { 0.4, 0.2 }, 
        new double[] { 0.2, 0.3 } 
      };
      double[] demand = new double[] { 1900, 1500, 500 };
      double[] limit = new double[] { 9000, 6000 };
      double[] cost = new double[] { 20, 15 };

      DataSet dataSet = new DataSet();
      #region Fill DataSet
      DataTable table = new DataTable("Yield");
      dataSet.Tables.Add(table);
      table.Columns.Add("Product", typeof(string));
      table.Columns.Add("Country", typeof(string));
      table.Columns.Add("Yield", typeof(double));

      for (int p = 0; p &amp;lt; products.Length; p++) {
        for (int c = 0; c &amp;lt; countries.Length; c++) {
          DataRow row = table.NewRow();
          row[0] = products[p];
          row[1] = countries[c];
          row[2] = yield[p][c];
          table.Rows.Add(row);
        }
      }

      table = new DataTable("Demand");
      dataSet.Tables.Add(table);
      table.Columns.Add("Product", typeof(string));
      table.Columns.Add("Demand", typeof(double));
      for (int p = 0; p &amp;lt; products.Length; p++) {
        DataRow row = table.NewRow();
        row[0] = products[p];
        row[1] = demand[p];
        table.Rows.Add(row);
      }

      table = new DataTable("Limit");
      dataSet.Tables.Add(table);
      table.Columns.Add("Country", typeof(string));
      table.Columns.Add("Limit", typeof(double));
      for (int c = 0; c &amp;lt; countries.Length; c++) {
        DataRow row = table.NewRow();
        row[0] = countries[c];
        row[1] = limit[c];
        table.Rows.Add(row);
      }

      table = new DataTable("Cost");
      dataSet.Tables.Add(table);
      table.Columns.Add("Country", typeof(string));
      table.Columns.Add("Cost", typeof(double));
      for (int c = 0; c &amp;lt; countries.Length; c++) {
        DataRow row = table.NewRow();
        row[0] = countries[c];
        row[1] = cost[c];
        table.Rows.Add(row);
      }
      #endregion

      return dataSet;
    }
&lt;/PRE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9567262" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx">Solver Foundation</category><category domain="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx">optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/INFORMS/default.aspx">INFORMS</category></item><item><title>Simple matrix, vector, permutation utilities</title><link>http://blogs.msdn.com/natbr/archive/2009/03/24/simple-matrix-vector-permutation-utilities.aspx</link><pubDate>Wed, 25 Mar 2009 07:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9506333</guid><dc:creator>Nathan Brixius</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/natbr/comments/9506333.aspx</comments><wfw:commentRss>http://blogs.msdn.com/natbr/commentrss.aspx?PostID=9506333</wfw:commentRss><wfw:comment>http://blogs.msdn.com/natbr/rsscomments.aspx?PostID=9506333</wfw:comment><description>&lt;P&gt;I am going to be rolling out the rest of my branch-and-bound algorithm in the next few posts.&amp;nbsp; To make that easier, in this post I introduce some common matrix, vector, and permutation methods.&amp;nbsp; It turns out that for technical computing applications, C#'s &lt;STRONG&gt;extension&lt;/STRONG&gt; methods (introduced in 3.0) are awesome.&amp;nbsp; With vectors it's great because you retain the control of having direct array access, but you get the nice object-oriented notation.&lt;/P&gt;
&lt;P&gt;I've left out comments and error-checking, and it's not super-optimized,&amp;nbsp;but you get the idea.&amp;nbsp; None of these methods end up being the bottleneck.&amp;nbsp; Most of the methods are obvious, but I do want to comment on the permutation methods.&amp;nbsp; The goal of QAP is to find an optimal assignment of facilities to locations, represented as a permutation.&amp;nbsp; In the course of our branch-and-bound algorithm, we'll be making partial assignments - that is, only some of the entries in the permutation will be filled in.&amp;nbsp; By convention, p[i] == -1 will mean that facility i is unassigned.&amp;nbsp; An index where p[i] &amp;lt; 0 is called "unused".&amp;nbsp; When we branch, we'll want to pick an unused facility (or location), and try assigning all unused locations (or facilities) to it.&amp;nbsp;&amp;nbsp; The use of C#'s &lt;STRONG&gt;iterator&lt;/STRONG&gt; and &lt;STRONG&gt;yield&lt;/STRONG&gt; concepts really help here.&lt;/P&gt;
&lt;P&gt;That said, here's the code.&lt;/P&gt;&lt;PRE&gt;  public static class MatrixUtilities {
    #region Vector
    public static void ConstantFill&lt;T&gt;(this T[] data, T val) {
      for (int i = 0; i &amp;lt; data.Length; i++) {
        data[i] = val;
      }
    }

    public static int ArgMin(this double[] data, out double best) {
      if (data.Length == 0) {
        best = Double.MinValue;
        return -1;
      }
      int iBest = 0;
      best = data[0];
      for (int i = 1; i &amp;lt; data.Length; i++) {
        if (best &amp;gt; data[i]) {
          best = data[i];
          iBest = i;
        }
      }
      return iBest;
    }

    public static int ArgMax(this double[] data, out double best) {
      if (data.Length == 0) {
        best = Double.MinValue;
        return -1;
      }
      int iBest = 0;
      best = data[0];
      for (int i = 1; i &amp;lt; data.Length; i++) {
        if (best &amp;lt; data[i]) {
          best = data[i];
          iBest = i;
        }
      }
      return iBest;
    }
    #endregion

    #region Permutation
    public static void Swap(this int[] p, int i, int j) {
      int temp = p[i];
      p[i] = p[j];
      p[j] = temp;
    }

    public static int FindUnused(this int[] data, int index) {
      foreach (int unused in data.UnusedIndices()) {
        if (index-- &amp;lt;= 0) {
          return unused;
        }
      }
      return -1;
    }

    public static IEnumerable&lt;INT&gt; UnusedIndices(this int[] data) {
      for (int i = 0; i &amp;lt; data.Length; i++) {
        if (data[i] &amp;lt; 0) {
          yield return i;
        }
      }
    }

    public static string PermutationToString(this int[] p, bool oneBased) {
      StringBuilder build = new StringBuilder(p.Length * 4);
      int width = ((int)Math.Log10(p.Length)) + 2;
      build.Append("[");
      for (int i = 0; i &amp;lt; p.Length; i++) {
        int index = oneBased ? p[i] + 1 : p[i];
        build.Append(index.ToString().PadLeft(width));
      }
      build.Append("]");
      return build.ToString();
    }
    #endregion

    #region Matrix

    public static string MatrixToString(this double[][] A) {
      if (A != null) {
        StringBuilder build = new StringBuilder(A.Length * A.Length * 3);
        for (int i = 0; i &amp;lt; A.Length; i++) {
          if (A[i] != null) {
            for (int j = 0; j &amp;lt; A[i].Length; j++) {
              build.AppendFormat("{0,4}", A[i][j]);
              build.Append(" ");
            }
            build.AppendLine();
          }
        }
        return build.ToString();
      }
      return null;
    }

    public static double[][] NewMatrix(int m, int n) {
      double[][] M = new double[m][];
      for (int i = 0; i &amp;lt; M.Length; i++) {
        M[i] = new double[n];
      }
      return M;
    }

    public static double[][] NewMatrix(int n) {
      return NewMatrix(n, n);
    }
    #endregion
  }
&lt;/PRE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9506333" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/natbr/archive/tags/QAP/default.aspx">QAP</category><category domain="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx">combinatorial optimization</category><category domain="http://blogs.msdn.com/natbr/archive/tags/linear+algebra/default.aspx">linear algebra</category></item></channel></rss>