<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Nathan Brixius</title><subtitle type="html" /><id>http://blogs.msdn.com/natbr/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/natbr/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2009-06-02T07:45:00Z</updated><entry><title>Using Solver Foundation's Unconstrained Nonlinear Solver</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/10/15/using-solver-foundation-s-unconstrained-nonlinear-solver.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/10/15/using-solver-foundation-s-unconstrained-nonlinear-solver.aspx</id><published>2009-10-15T22:48:00Z</published><updated>2009-10-15T22:48:00Z</updated><content type="html">&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;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx" /><category term="Solver Foundation" scheme="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /></entry><entry><title>Announcing Brixius 2.0</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/10/09/announcing-brixius-2-0.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/10/09/announcing-brixius-2-0.aspx</id><published>2009-10-10T03:34:00Z</published><updated>2009-10-10T03:34:00Z</updated><content type="html">&lt;P&gt;My wife gave birth to a healthy baby daugther last night!&amp;nbsp; Mom, baby, (and dad) are all doing well.&amp;nbsp;I will be spending some time at home with the newest addition to our family, so I will go easy on the blog posts for awhile.&amp;nbsp;When I come back I will do one on our nonlinear solver, more about &lt;A href="http://blogs.msdn.com/natbr/archive/2009/10/08/announcing-solver-foundation-2-0.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/10/08/announcing-solver-foundation-2-0.aspx"&gt;Solver Foundation 2.0&lt;/A&gt;, and finish up my QAP series.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9905672" width="1" height="1"&gt;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="Personal" scheme="http://blogs.msdn.com/natbr/archive/tags/Personal/default.aspx" /></entry><entry><title>Announcing Solver Foundation 2.0</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/10/08/announcing-solver-foundation-2-0.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/10/08/announcing-solver-foundation-2-0.aspx</id><published>2009-10-08T20:25:00Z</published><updated>2009-10-08T20:25:00Z</updated><content type="html">&lt;P&gt;I'm pleased to announce the release of Solver Foundation 2.0, available at &lt;A href="http://www.solverfoundation.com/" target=_blank mce_href="http://www.solverfoundation.com"&gt;solverfoundation.com&lt;/A&gt;.&amp;nbsp; We've added capabilities that allow Solver Foundation to solve important categories of optimization problems, improved the performance and stability our existing solvers, and improved our Visual Studio and Office tools to make model building and analysis easier.&amp;nbsp; Here are a few of the highlights:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Excel 2007 add-in.&lt;/STRONG&gt;&amp;nbsp; We have completely overhauled the Excel 2007 add-in to make it easier to build, debug, and deploy models.&amp;nbsp; Here is a screenshot from the new add-in:&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 1235px; HEIGHT: 809px" title="Solver Foundation Add-In for Excel 2007" alt="Solver Foundation Add-In for Excel 2007" src="http://blogs.msdn.com/photos/nathan_brixius/images/9905151/original.aspx" width=1235 height=809 mce_src="http://blogs.msdn.com/photos/nathan_brixius/images/9905151/original.aspx"&gt;&lt;/P&gt;
&lt;P&gt;As you can see, the building blocks of a model (Parameters, Decisions, Goals, Constraints) are built through a more task-centered user-interface, reducing the need for hand-coding OML.&amp;nbsp; Data binding has been simplified, and decision (output) data binding is now supported.&amp;nbsp; Models can include random parameters and recourse decisions to build stochastic models.&amp;nbsp; Finally, the add-in now features the ability to deploy models directly to C# (for use within a Visual Studio project) or to OMLX (for use within SharePoint for server-side calculation).&amp;nbsp; We're trying to simplify the modeling process and bridge the gap between modelers, developers, and business decision makers.&amp;nbsp; Export to C# is this easy:&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 864px; HEIGHT: 540px" title="Export to C# from the add-in is easy." alt="Export to C# from the add-in is easy." src="http://blogs.msdn.com/photos/nathan_brixius/images/9905154/original.aspx" width=864 height=540 mce_src="http://blogs.msdn.com/photos/nathan_brixius/images/9905154/original.aspx"&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Simulation and stochastic programming.&lt;/STRONG&gt;&amp;nbsp; I previewed our stochastic modeling and solving features in a &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;previous post&lt;/A&gt;.&amp;nbsp; It is now possible to include random parameters in OML or SFS code&amp;nbsp;to build stochastic models.&amp;nbsp; Solver Foundation includes powerful sampling engines and decomposition techniques to solve large stochastic models quickly, and provides reporting information that tells you how the uncertainty affects the model.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;MIP performance improvements.&lt;/STRONG&gt;&amp;nbsp; The new &lt;A href="http://www.gurobi.com/" target=_blank mce_href="http://www.gurobi.com"&gt;Gurobi&lt;/A&gt; 2.0 solver is included as the default MIP solver in Solver Foundation.&amp;nbsp; The Gurobi solver's performance and functionality has been improved in a number of important ways, as described &lt;A href="http://www.gurobi.com/html/products.html" target=_blank mce_href="http://www.gurobi.com/html/products.html"&gt;here&lt;/A&gt;. The combination of Solver Foundation Services' clean, powerful managed code API and Gurobi's world-class MIP solver gets even better in our 2.0.&amp;nbsp; Our own in-house, purely managed MIP solver has been greatly improved as well.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Second Order Conic Programming.&lt;/STRONG&gt;&amp;nbsp; &lt;A href="http://blogs.msdn.com/natbr/archive/2009/10/01/solver-foundation-2-0-preview-second-order-conic-programming.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/10/01/solver-foundation-2-0-preview-second-order-conic-programming.aspx"&gt;As I mentioned in this post&lt;/A&gt;, Solver Foundation 2.0's interior-point solver is now capable of solving large-scale second order conic programming models.&amp;nbsp; SOCP models contain nonlinear conic constraints and are often countered in robust optimization and financial models.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Constraint Solver improvements.&lt;/STRONG&gt;&amp;nbsp; We have developed new metaheuristics and global constraints for our CP solver in conjunction with the gang in MSR Cambridge.&amp;nbsp; Watch &lt;A href="http://blogs.msdn.com/lengningliu/" target=_blank mce_href="http://blogs.msdn.com/lengningliu/"&gt;Lengning's blog&lt;/A&gt; for more details.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;F# integration.&amp;nbsp; &lt;/STRONG&gt;We've heard a lot of positive noises about our &lt;A href="http://msdn.microsoft.com/en-us/fsharp/default.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/fsharp/default.aspx"&gt;F#&lt;/A&gt; integration - it's better in 2.0.&amp;nbsp; Our F# optimization DSL has been improved and now incorporates units-of-measure as described &lt;A href="http://blogs.msdn.com/natbr/archive/2009/09/13/solver-foundation-2-0-preview-f-odsl.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/09/13/solver-foundation-2-0-preview-f-odsl.aspx"&gt;in this post&lt;/A&gt;.&amp;nbsp; Special thanks to the F# team for their help on this important piece of the puzzle.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;And more.&lt;/STRONG&gt;&amp;nbsp; Submodel support, better SOS1/SOS2 support, improved reporting, improved model analysis and error messages, more solver plug-ins, better performance and memory&amp;nbsp; usage across the board.&lt;/P&gt;
&lt;P&gt;The release of Solver Foundation 2.0 is the culmination of&amp;nbsp;one year of hard work by the team.&amp;nbsp; I hope you will give it a try (&lt;A href="http://code.msdn.microsoft.com/solverfoundation/Release/ProjectReleases.aspx" target=_blank mce_href="http://code.msdn.microsoft.com/solverfoundation/Release/ProjectReleases.aspx"&gt;the Express version is freely available&lt;/A&gt;) and provide your feedback either through the blog or through our &lt;A href="http://code.msdn.microsoft.com/solverfoundation/Thread/List.aspx" target=_blank mce_href="http://code.msdn.microsoft.com/solverfoundation/Thread/List.aspx"&gt;MSDN forum&lt;/A&gt;.&amp;nbsp; Getting this stuff right - and covering the scenarios that people care about - is hard work and it takes time.&amp;nbsp; We've come a long way in a year, but there's so much more we want to do.&amp;nbsp; As always, the team appreciates honest feedback, good and bad.&amp;nbsp; We're serious about listening to that feedback to make Solver Foundation better.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9905061" width="1" height="1"&gt;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="Solver Foundation" scheme="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx" /><category term="F#" scheme="http://blogs.msdn.com/natbr/archive/tags/F_2300_/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="OML" scheme="http://blogs.msdn.com/natbr/archive/tags/OML/default.aspx" /><category term="Gurobi" scheme="http://blogs.msdn.com/natbr/archive/tags/Gurobi/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /><category term="interior point methods" scheme="http://blogs.msdn.com/natbr/archive/tags/interior+point+methods/default.aspx" /><category term="Stochastic Programming" scheme="http://blogs.msdn.com/natbr/archive/tags/Stochastic+Programming/default.aspx" /><category term="Simulation" scheme="http://blogs.msdn.com/natbr/archive/tags/Simulation/default.aspx" /><category term="SOCP" scheme="http://blogs.msdn.com/natbr/archive/tags/SOCP/default.aspx" /></entry><entry><title>Solver Foundation 2.0 Preview: Second Order Conic Programming</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/10/01/solver-foundation-2-0-preview-second-order-conic-programming.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/10/01/solver-foundation-2-0-preview-second-order-conic-programming.aspx</id><published>2009-10-02T07:32:00Z</published><updated>2009-10-02T07:32:00Z</updated><content type="html">&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;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx" /><category term="Solver Foundation" scheme="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /><category term="interior point methods" scheme="http://blogs.msdn.com/natbr/archive/tags/interior+point+methods/default.aspx" /><category term="SOCP" scheme="http://blogs.msdn.com/natbr/archive/tags/SOCP/default.aspx" /></entry><entry><title>Using the Solver Foundation Interior Point Solver</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/09/24/using-the-solver-foundation-interior-point-solver.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/09/24/using-the-solver-foundation-interior-point-solver.aspx</id><published>2009-09-25T00:24:00Z</published><updated>2009-09-25T00:24:00Z</updated><content type="html">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;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx" /><category term="Solver Foundation" scheme="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /><category term="interior point methods" scheme="http://blogs.msdn.com/natbr/archive/tags/interior+point+methods/default.aspx" /></entry><entry><title>Solver Foundation 2.0 Preview: F# ODSL</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/09/13/solver-foundation-2-0-preview-f-odsl.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/09/13/solver-foundation-2-0-preview-f-odsl.aspx</id><published>2009-09-14T07:08:00Z</published><updated>2009-09-14T07:08:00Z</updated><content type="html">&lt;P&gt;&lt;A href="http://blogs.msdn.com/lengningliu/archive/2009/09/04/optimization-domain-specific-language-in-f-with-units-of-measure.aspx" target=_blank mce_href="http://blogs.msdn.com/lengningliu/archive/2009/09/04/optimization-domain-specific-language-in-f-with-units-of-measure.aspx"&gt;Lengning Liu has written a great post&lt;/A&gt; that highlights another exciting Solver Foundation 2.0 area: a Solver Foundation ODSL in &lt;A href="http://msdn.microsoft.com/en-us/fsharp/default.aspx" mce_href="http://msdn.microsoft.com/en-us/fsharp/default.aspx"&gt;F#&lt;/A&gt;.&amp;nbsp;&amp;nbsp;(F# is a functional programming language for .Net.)&amp;nbsp; The ODSL provides an intuitive, cool way to express LP and MIP problems.&amp;nbsp; My favorite addition to the ODSL is units of measure.&amp;nbsp; Parameters and decisions can be annotated with their units of measure, and the associated consistency checks are enforced by F# at compile time.&amp;nbsp; This is a great way to provide clarity to models as well as enforce correctness.&amp;nbsp; Here's an example from Lengning's post:&amp;nbsp;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;let&lt;/SPAN&gt;&lt;/B&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt; a = 20.0&amp;lt;Dollar/Barrel&amp;gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;let&lt;/SPAN&gt;&lt;/B&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt; b = 15.0&amp;lt;Dollar/Barrel&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;let&lt;/SPAN&gt;&lt;/B&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt; sa = var&amp;lt;Barrel/Day&amp;gt;()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;let&lt;/SPAN&gt;&lt;/B&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt; vz = var&amp;lt;_&amp;gt;()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5; tab-stops: 102.15pt" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5; tab-stops: 102.15pt" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;minimise (a * sa + b * vz)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;where&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: ES" lang=ES&gt;[&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: ES" lang=ES&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;0.3 * sa + 0.4 * vz &amp;gt;= 2000.&amp;lt;_&amp;gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: ES" lang=ES&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;0.4 * sa + 0.2 * vz &amp;gt;= 1500.&amp;lt;_&amp;gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: ES" lang=ES&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;0.2 * sa + 0.3 * vz &amp;gt;= 500.&amp;lt;_&amp;gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: ES" lang=ES&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;sa &amp;lt;= 9000.&amp;lt;_&amp;gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;vz &amp;lt;= 6000.&amp;lt;_&amp;gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;sa &amp;gt;= 0.&amp;lt;_&amp;gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;vz &amp;gt;= 0.&amp;lt;_&amp;gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none; mso-yfti-cnfc: 5" class=MsoNormal&gt;&lt;B&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes; mso-ansi-language: EN-GB" lang=EN-GB&gt;]&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9895223" width="1" height="1"&gt;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="Solver Foundation" scheme="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx" /><category term="F#" scheme="http://blogs.msdn.com/natbr/archive/tags/F_2300_/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="OML" scheme="http://blogs.msdn.com/natbr/archive/tags/OML/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /></entry><entry><title>Nash equilibria and 4th down, continued</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/09/11/nash-equilibria-and-4th-down-continued.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/09/11/nash-equilibria-and-4th-down-continued.aspx</id><published>2009-09-12T07:30:00Z</published><updated>2009-09-12T07:30:00Z</updated><content type="html">&lt;P&gt;I left a small cliffhanger in my &lt;A href="http://blogs.msdn.com/natbr/archive/2009/09/08/dynamic-programming-nash-equilibria-and-going-for-it-on-4th-down.aspx" target=_blank mce_href="http://blogs.msdn.com/natbr/archive/2009/09/08/dynamic-programming-nash-equilibria-and-going-for-it-on-4th-down.aspx"&gt;last post&lt;/A&gt;. After a long week I finally had a chance to read through the &lt;A href="http://www.aeaweb.org/annual_mtg_papers/2008/2008_386.pdf" mce_href="http://www.aeaweb.org/annual_mtg_papers/2008/2008_386.pdf"&gt;Adams paper&lt;/A&gt; about estimating the value of "going for it" on 4th down.&amp;nbsp; I admit I was a little bit let down.&amp;nbsp;&amp;nbsp; As a reminder - the question is what action a football team should take on fourth down.&amp;nbsp; Failure to gain the necessary yards means the ball is turned over to the opposing side, kicking turns over the ball but with better field position, and making the first down allows the drive to continue, potentially leading to more points.&amp;nbsp; The conclusion of the Romer paper was that coaches are too conservative and kick the ball away in situations where they should&amp;nbsp;go for it instead.&lt;/P&gt;
&lt;P&gt;Adams hits the nail on the head by asserting that the results of the Romer paper just do not pass the "smell test".&amp;nbsp; It's nuts to suggest that it's a good idea to go for it on 4th and 4 on your own 25 yard line.&amp;nbsp; But that leaves us only with more questions - is the conclusion of the Romer paper still valid, even if overstated?&amp;nbsp; Can we identify a flaw in the reasoning?&amp;nbsp; Is there a better way to model the problem?&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Adams first suggestion for improving the model is to include more historical data.&amp;nbsp; Adams and Romer both claim it's hard to come up with a good model for the "going for it" problem because teams seldom go for it on fourth down in practice - data is hard to come by.&amp;nbsp;&amp;nbsp;&amp;nbsp; Romer and Adams both use game data from the 1998 - 2000 seasons, but Adams uses data from the entire game, not just the first quarter.&amp;nbsp; But why not include more recent data?&amp;nbsp; [The Adams paper was written in '06, so he could have doubled the data set.&amp;nbsp; We have a couple more seasons-worth of data now.]&amp;nbsp; So I'm not sure I even buy the premise that data is lacking.&lt;/P&gt;
&lt;P&gt;Adams' second approach is to use Madden '07 to simulate 4th down situations.&amp;nbsp; I initially thought this was a really cool idea, and it kind of is, and then I remembered something I once read.&amp;nbsp; &lt;A href="http://www.baseballthinkfactory.org/files/newsstand/discussion/ids_news_iu_researcher_designs_football_strategy_device/" target=_blank mce_href="http://www.baseballthinkfactory.org/files/newsstand/discussion/ids_news_iu_researcher_designs_football_strategy_device/"&gt;Madden himself asked the designers at EA to make 4th downs more difficult to convert!&lt;/A&gt;&amp;nbsp; You cannot find a better example of &lt;A href="http://en.wikipedia.org/wiki/John_Kenneth_Galbraith" mce_href="http://en.wikipedia.org/wiki/John_Kenneth_Galbraith"&gt;Galbraith's&lt;/A&gt; notion of "conventional wisdom" in action.&amp;nbsp; So as far as I am concerned, you have to throw out the middle section of the paper.&amp;nbsp; Madden is not a simulation:&amp;nbsp;it is pretending to be a simulation.&amp;nbsp; It wants to make you feel like you are experiencing real NFL football.&amp;nbsp; But the problem is that we as players do not make decisions the way that GMs, coaches, and players do.&amp;nbsp; Our motivations are completely different, and there are no real consequences for our actions (other than bragging rights over your roommate).&amp;nbsp; My GM will not fire me if I go for it on 4th and 5 on my own 25.&amp;nbsp; Thus the game must be tuned to correct for this, otherwise you will &lt;A href="http://www.youtube.com/watch?v=8PBvOxicz-0" mce_href="http://www.youtube.com/watch?v=8PBvOxicz-0"&gt;get Tecmo-like gameplay&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The last section proposes a game-theoretic approach.&amp;nbsp; Adams introduces a zero-sum game with the offense and defense as opponents.&amp;nbsp; The offense and defense both have the choice of choosing a pass- or run-oriented strategy.&amp;nbsp; The payoffs depend on their choices.&amp;nbsp; Adams points out that this is a "simplified version of reality."&amp;nbsp; (It's very close to the original &lt;A href="http://en.wikipedia.org/wiki/Tecmo_Bowl" mce_href="http://en.wikipedia.org/wiki/Tecmo_Bowl"&gt;Tecmo Bowl&lt;/A&gt;&amp;nbsp;- two choices instead of four.)&amp;nbsp; He uses this approach primarily to make the point that it is not a good idea (as Romer proposes) to use third down data to model fourth down choices, because the payoffs change enough to matter.&amp;nbsp; It is an interesting line of argument for the claim that Romer's conclusions are overstated, but it does not provide insight into how to better model the problem.&lt;/P&gt;
&lt;P&gt;Anyway, in the course of poking around the web I came across the&lt;A href="http://www.pigskinrevolution.com/" mce_href="http://www.pigskinrevolution.com/"&gt; ZEUS Football simulation engine&lt;/A&gt;. It is frequently referenced in the NYTimes "5th down" blog. For example, &lt;A href="http://fifthdown.blogs.nytimes.com/2009/01/08/zeus-reviews-the-colts-option-of-an-intentional-safety/#more-1961" mce_href="http://fifthdown.blogs.nytimes.com/2009/01/08/zeus-reviews-the-colts-option-of-an-intentional-safety/#more-1961"&gt;here&lt;/A&gt; is an interesting discussion about taking an intentional safety late in the game.&amp;nbsp; (I won't bother to explain what that means, because if you have made it this far, you clearly already know what I am talking about.)&lt;/P&gt;
&lt;P&gt;All the questions I raised at the beginning of this post are probably best answered by a simulation engine.&amp;nbsp; Which reminds me - did I mention that &lt;A href="http://blogs.msdn.com/natbr/archive/2009/09/03/solver-foundation-2-0-preview-simulation-and-stochastic-programming.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/09/03/solver-foundation-2-0-preview-simulation-and-stochastic-programming.aspx"&gt;Solver Foundation is adding stochastic capabilities for our version 2&lt;/A&gt;?&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9894483" width="1" height="1"&gt;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="Fun" scheme="http://blogs.msdn.com/natbr/archive/tags/Fun/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /><category term="Simulation" scheme="http://blogs.msdn.com/natbr/archive/tags/Simulation/default.aspx" /><category term="sabermetrics" scheme="http://blogs.msdn.com/natbr/archive/tags/sabermetrics/default.aspx" /></entry><entry><title>Dynamic programming, Nash equilibria, and going for it on 4th down</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/09/08/dynamic-programming-nash-equilibria-and-going-for-it-on-4th-down.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/09/08/dynamic-programming-nash-equilibria-and-going-for-it-on-4th-down.aspx</id><published>2009-09-09T01:22:00Z</published><updated>2009-09-09T01:22:00Z</updated><content type="html">&lt;P&gt;Last weekend marked the first big college football Saturday of the year.&amp;nbsp; The only game I really cared about (now that I am married and have kids) was the Northern Iowa – Iowa game: I went to &lt;A href="http://www.uiowa.edu/" mce_href="http://www.uiowa.edu"&gt;Iowa&lt;/A&gt;, and I grew up in Cedar Falls (home of the UNI campus).&amp;nbsp; &lt;A href="http://scores.espn.go.com/ncf/recap?gameId=292482294" target=_blank mce_href="http://scores.espn.go.com/ncf/recap?gameId=292482294"&gt;Iowa came from behind and won 17-16 after blocking two field goal attempts in the final seconds&lt;/A&gt;.&amp;nbsp; My brother and I were talking on the phone during the 4th quarter.&amp;nbsp; My brother, a UNI fan, was bothered by the conservative coaching that he feels let Iowa back into the game, and that spun into a more general conversation about risk-averse coaching.&amp;nbsp; I don't know anything about sabermetrics, but I did read &lt;A title=http://www.amazon.com/Moneyball-Art-Winning-Unfair-Game/dp/0393057658 target=_blank&gt;Moneyball&lt;/A&gt;, and I love sports.&lt;/P&gt;
&lt;P&gt;Our conversation reminded me of a paper by economist &lt;A href="http://elsa.berkeley.edu/~dromer/" mce_href="http://elsa.berkeley.edu/~dromer/"&gt;David Romer&lt;/A&gt; that I had always intended on reading: “&lt;A href="http://emlab.berkeley.edu/users/dromer/papers/nber9024.pdf" target=_blank mce_href="http://emlab.berkeley.edu/users/dromer/papers/nber9024.pdf"&gt;It’s Fourth Down and What Does the Bellman Equation Say?&lt;/A&gt;”&amp;nbsp; (I actually recommend &lt;A href="http://blogs.msdn.com/controlpanel/blogs/o%09http:/elsa.berkeley.edu/~dromer/papers/PAPER_NFL_JULY05_FORWEB_CORRECTED.pdf" target=_blank mce_href="http://blogs.msdn.com/controlpanel/blogs/o%09http:/elsa.berkeley.edu/~dromer/papers/PAPER_NFL_JULY05_FORWEB_CORRECTED.pdf"&gt;this updated 2005 version&lt;/A&gt;.)&amp;nbsp; So I read it. &amp;nbsp;It received some attention from the sports world when it came out because Romer’s claim is that the conventional wisdom is wrong: it’s often a much better idea to try to convert on 4th down rather than kick the ball away to the other team.&amp;nbsp;&amp;nbsp;It depends on field position and yards-to-go, of course.&amp;nbsp; He sets up a not-too-complicated dynamic programming model where he is able to place values on particular game situations, and then compares the difference between kicking and “going for it”.&amp;nbsp; It’s interesting but I have some problems with it – in particular the use of 3rd down outcomes rather than 4th down outcomes.&amp;nbsp; The justification is that because teams don’t go for it on 4th down very often there is not enough data, so 3rd down data is a reasonable substitute.&amp;nbsp;&amp;nbsp;I have issues with this because for one thing,&amp;nbsp;playcalling is very different on 3rd down, especially when one is&amp;nbsp;approaching field goal range.&amp;nbsp; Players are also taught to handle 3rd down differently - throw the ball away and avoid taking a sack.&amp;nbsp;&amp;nbsp;Romer&amp;nbsp;does address these sorts of issues, but it still bothers me. &lt;/P&gt;
&lt;P&gt;To overcome the lack of 4th down “going for it” data, Christopher Adams from the FTC (!) uses Madden NFL 07 (!!) for simulation purposes and constructs a game theoretic model for 4th down attempts&lt;A href="http://www.aeaweb.org/annual_mtg_papers/2008/2008_386.pdf" target=_blank mce_href="http://www.aeaweb.org/annual_mtg_papers/2008/2008_386.pdf"&gt; in this paper&lt;/A&gt;.&amp;nbsp; He&amp;nbsp;comes to a different conclusion: the conventional wisdom may not be so bad after all.&amp;nbsp; I am looking forward to reading the Adams paper in detail - it's in my backpack.&amp;nbsp; I hope to do some experimentation in this area once I get a grip on the concepts.&amp;nbsp; I would like to write a paper about the prevent defense that Gregg Easterbrook and Bill Simmons despise so much!&amp;nbsp; But right now, I’ve got to get back to work ;)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9892847" width="1" height="1"&gt;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="Fun" scheme="http://blogs.msdn.com/natbr/archive/tags/Fun/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /><category term="Simulation" scheme="http://blogs.msdn.com/natbr/archive/tags/Simulation/default.aspx" /><category term="sabermetrics" scheme="http://blogs.msdn.com/natbr/archive/tags/sabermetrics/default.aspx" /></entry><entry><title>Solver Foundation 2.0 Preview: Simulation and Stochastic Programming</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/09/03/solver-foundation-2-0-preview-simulation-and-stochastic-programming.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/09/03/solver-foundation-2-0-preview-simulation-and-stochastic-programming.aspx</id><published>2009-09-03T19:28:00Z</published><updated>2009-09-03T19:28:00Z</updated><content type="html">&lt;P&gt;I'm back from ISMP and&amp;nbsp;helping to put the finishing touches on &lt;A href="http://www.solverfoundation.com/" mce_href="http://www.solverfoundation.com"&gt;Solver Foundation&lt;/A&gt; 2.0.&amp;nbsp;&lt;A href="http://code.msdn.microsoft.com/solverfoundation" mce_href="http://code.msdn.microsoft.com/solverfoundation"&gt; In our first version&lt;/A&gt; we introduced: our declarative modeling language OML; Solver Foundation Services, which provides a powerful, consistent .Net API for modeling and solving a wide range of decision problems; a set of solvers for linear, quadratic, mixed integer, constraint, and unconstrained nonlinear programming; &lt;A href="http://blogs.msdn.com/natbr/archive/2009/05/07/solver-foundation-tsp-part-ii-directives-solver-plugins-model-libraries.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/05/07/solver-foundation-tsp-part-ii-directives-solver-plugins-model-libraries.aspx"&gt;third-party solver plug-in support&lt;/A&gt;; and an Excel add-in that provides easy access to all of Solver Foundation's functionality through Office 2007.&amp;nbsp; Our aim in version 2.0 is to make it easier for non-experts to model and solve problems, and to expand the range of problems that can be solved using Solver Foundation.&amp;nbsp;&amp;nbsp;I will spend the next few posts talking about our plans for 2.0.&lt;/P&gt;
&lt;P&gt;Many real-world problems involve uncertainty.&amp;nbsp; For example, task durations, sales estimates, rate of return, and so on. Simulation and/or stochastic programming techniques are often used to account for randomness, but applying such techniques can often be quite tricky.&amp;nbsp; In Solver Foundation 2.0 we are adding OML, Solver Foundation Services and solver support for linear stochastic models.&amp;nbsp; The two new modeling concepts are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Random parameters&lt;/STRONG&gt; are used to model randomness.&amp;nbsp; They can be discrete or continuous.&amp;nbsp; They can be used where (non-random) parameters or constants would normally be used in constraints.&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;A special type of random parameter is a Scenarios parameter.&amp;nbsp; In this case a list of scenarios are given where each scenario contains a value and a probability.&amp;nbsp; For example, to model weather we might have a "rainy" scenario, a "normal" scenario, and a "dry" scenario.&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Recourse decisions&lt;/STRONG&gt;&amp;nbsp;are decisions that&amp;nbsp;are made in response to the realization of a random parameter.&amp;nbsp; For example, if the weather turns out to be dry, we may not be able to produce enough of a certain crop and may need to purchase it from someone else.&amp;nbsp; In this case, the purchase amount is a recourse decision.&amp;nbsp; Recourse decisions are sometimes called "second-stage" decision because such decisions can be made only after the randomness is resolved.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;As you will see in a moment, if you know how to build regular models using OML, building models with random parameters and recourse decisions will be no problem.&amp;nbsp; Solver Foundation Services will contain new APIs that allow for stochastic modeling using random parameters and recourse decisions.&amp;nbsp; Indexed random parameters and data binding will be fully supported.&amp;nbsp; We will support the following distributions in V2:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Continuous:&lt;/STRONG&gt; Normal (Gaussian), Uniform, Exponential, Log normal, Scenario-based.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Discrete:&lt;/STRONG&gt; Uniform, Geometric, Binomial&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Here is a simple OML example.&amp;nbsp; It is a simple production planning problem with scalar input (&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;here is a non-stochastic sample in C#&lt;/A&gt;).&amp;nbsp; We introduce recourse decisions&amp;nbsp;that represent the amount of pre-refined product to buy, in case demand cannot be met by production.&amp;nbsp; The demand for each product is random; the demand for gas is modeled using two scenarios of equal probability, the others are uniformly distributed.&amp;nbsp; Not very realistic, but I wanted to cram all the new concepts in a short model!&amp;nbsp; Indexed random parameters are of course possible.&amp;nbsp; In that case you will be able to use data binding to define the parameters associated with the distributions - keeping a clean separation between data and model, and allowing for easy experimentation.&lt;FONT size=2 face=Consolas&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&lt;BR&gt;Model[&amp;nbsp;&lt;BR&gt;&amp;nbsp; Decisions[Reals[0, Infinity], SaudiArabia, Venezuela],&lt;BR&gt;&amp;nbsp; Decisions[Reals[0, Infinity],&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // To define a recourse decision, just wrap Recourse[] around it.&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Recourse[GasBuy], Recourse[JetFuelBuy], Recourse[LubricantBuy]&lt;BR&gt;&amp;nbsp; ], 
&lt;P&gt;&amp;nbsp; Parameters[&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Here is a scenario-based random parameter with two scenarios of&amp;nbsp;equal probability.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Scenarios[Reals[0, Infinity]],&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GasDemand = {{0.5, 1900}, {0.5, 2100}}&lt;BR&gt;&amp;nbsp; ],&lt;BR&gt;&lt;BR&gt;&amp;nbsp; // Here is a continuous random parameter.&amp;nbsp;&lt;BR&gt;&amp;nbsp; Parameters[UniformDistribution[1500, 1600], JetFuelDemand],&lt;BR&gt;&amp;nbsp; Parameters[UniformDistribution[400, 500], LubricantDemand],&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp; Goals[&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Minimize[ goal -&amp;gt; 20 * SaudiArabia+ 15 * Venezuela + (38.4 * GasBuy + 35.2 * JetFuelBuy + 28.8 * LubricantBuy) ]&lt;BR&gt;&amp;nbsp; ],&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp; Constraints[ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.3 * SaudiArabia + 0.4 * Venezuela + GasBuy &amp;gt;= GasDemand,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.4 * SaudiArabia + 0.2 * Venezuela + JetFuelBuy &amp;gt;= JetFuelDemand,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.2 * SaudiArabia + 0.3 * Venezuela+ LubricantBuy &amp;gt;= LubricantDemand,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SaudiArabia &amp;lt;= 9000,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Venezuela &amp;lt;= 6000&lt;BR&gt;&amp;nbsp; ]&lt;BR&gt;]&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;The modeling constructs are simple, but underneath the hood there is a lot going on: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Solver Foundation Services supports different sampling methods including Monte Carlo and Latin Hypercube.&amp;nbsp; Going beyond simple Monte Carlo often leads to better results in less time.&amp;nbsp;&amp;nbsp; &lt;/LI&gt;
&lt;LI&gt;Large problems can be solved efficiently using Benders decomposition.&amp;nbsp; &lt;/LI&gt;
&lt;LI&gt;Solver Foundation Services will have API support for tuning the behavior of the stochastic solver.&amp;nbsp; &lt;/LI&gt;
&lt;LI&gt;Our primary focus is on providing a satisfactory experience “out-of-the-box”, without having to resort to lots of tuning.&lt;BR&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9890996" width="1" height="1"&gt;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="Solver Foundation" scheme="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="OML" scheme="http://blogs.msdn.com/natbr/archive/tags/OML/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /><category term="Stochastic Programming" scheme="http://blogs.msdn.com/natbr/archive/tags/Stochastic+Programming/default.aspx" /><category term="Simulation" scheme="http://blogs.msdn.com/natbr/archive/tags/Simulation/default.aspx" /></entry><entry><title>Int'l Symposium on Mathematical Programming, Day 2</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/08/27/int-l-symposium-on-mathematical-programming-day-2.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/08/27/int-l-symposium-on-mathematical-programming-day-2.aspx</id><published>2009-08-28T06:22:00Z</published><updated>2009-08-28T06:22:00Z</updated><content type="html">&lt;P&gt;Here are my notes from the second day of &lt;A href="http://ismp2009.eecs.northwestern.edu/" mce_href="http://ismp2009.eecs.northwestern.edu/"&gt;ISMP&lt;/A&gt;.&amp;nbsp; (&lt;A href="http://blogs.msdn.com/natbr/archive/2009/08/26/int-l-symposium-on-mathematical-programming-day-1.aspx" mce_href="http://blogs.msdn.com/natbr/archive/2009/08/26/int-l-symposium-on-mathematical-programming-day-1.aspx"&gt;Here are my day 1 notes.&lt;/A&gt;)&amp;nbsp; I spent the whole day going to IPM talks:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;A href="http://www.sztaki.hu/~meszaros/" mce_href="http://www.sztaki.hu/~meszaros/"&gt;Meszaros&lt;/A&gt;&lt;/STRONG&gt;: Unfortunately I missed the plenary talk by Friedrich Eisenbrand due to microbrews.&amp;nbsp; I attended an IPM session after that - first up was Csaba Meszaros - interesting to hear from him because BPMPD has been such an impressive code for so many years.&amp;nbsp; His talk was about recent improvements in &lt;A href="http://www.sztaki.hu/~meszaros/bpmpd/" mce_href="http://www.sztaki.hu/~meszaros/bpmpd/"&gt;BPMPD&lt;/A&gt;.&amp;nbsp; BPMPD has been in continuous development for 15 years or so.&amp;nbsp; His recent work appears to focus on a) QCQP b) exploiting "hypersparsity".&amp;nbsp; He is using a primal-dual log barrier method&amp;nbsp; - not a primal-dual HSD method as we at &lt;A href="http://www.solverfoundation.com/" mce_href="http://www.solverfoundation.com"&gt;Solver Foundation&lt;/A&gt; have chosen for our SOCP solver.&amp;nbsp; So his handling of starting points and infeasibility detection is different.&amp;nbsp; He went into the tradeoffs between using augmented and normal systems for the search direction, which affect both performance and numerical stability.&amp;nbsp; He has implemented both and has logic on top to determine which to use.&amp;nbsp; He also talked about QCQP presolve, which often whittles down the size of "real" models substantially.&lt;BR&gt;&amp;nbsp;&lt;BR&gt;An interesting bit of trivia:&amp;nbsp;he showed a table that compared lines of code in various modules, "then and now":&lt;PRE&gt; 	2009	1981
Ordering	5700	155
Cholesky	2825	100
Backsolve	820	45
&lt;/PRE&gt;&lt;BR&gt;I think the difference is indicative of both Csaba's commitment to improving BPMPD as well as the number of practical issues you need to think about when building an industrial grade solver.&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;STRONG&gt;Bliek (IBM):&lt;/STRONG&gt; Next up - IPM session chair Christian Bliek from &lt;A href="http://www.ibm.com/" mce_href="http://www.ibm.com"&gt;IBM&lt;/A&gt;.&amp;nbsp; His talk was about barrier improvements in &lt;A href="http://www.ilog.com/products/cplex/" mce_href="http://www.ilog.com/products/cplex/"&gt;CPLEX&lt;/A&gt;.&amp;nbsp; For the single threaded case, CPLEX 12 is about 5% faster than 11 [note that these numbers are totally unofficial and any errors are my own].&amp;nbsp; With 4 threads it is about 20% better.&amp;nbsp; There was no magic bullet here, more tuning at the solver and algebra layer.&amp;nbsp; With a sophisticated solver such as CPLEX the improvements come through hard work, no tricks.&amp;nbsp; There was also some data on simplex vs. barrier.&amp;nbsp; For their complete set of their benchmark LPs, for problems that take 100 seconds or more barrier (without crossover) beats dual simplex on average.&amp;nbsp; If you allow crossover, then performance vs dual simplex is about even for small problems (~1s solution time) and after that crossover really takes over.&amp;nbsp; For problems that take 1000s and up, the geometric mean for the performance ratio against dual is 0.55.&amp;nbsp; So almost twice as fast.&lt;BR&gt;&amp;nbsp;&lt;BR&gt;For QP, barrier is way better than their active set approach.&amp;nbsp; Of course this does not take into account scenarios where warmstart could be used, where simplex rocks.&amp;nbsp; More on that later.&amp;nbsp; They also have&amp;nbsp;a "concurrent" setting, meaning to race the simplex &amp;amp; IPM solvers.&amp;nbsp; This setting gives the best results.&amp;nbsp; Solver Foundation Services has also supported this type of "transparent parallelism" since version 1.0. The last bit of the talk was about some experiments using PARDISO instead of the solver's own algebra stack.&amp;nbsp; Their conclusion was that using a "black box" linear algebra module shows potential.&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;STRONG&gt;Warmstart:&lt;/STRONG&gt; The last talk in the session was by Anthony Vannelli, who&amp;nbsp;talked about IPM warmstart.&amp;nbsp; He takes a very pragmatic approach and layed out a very sensible procedure for attacking the difficult problem of using the solution of an IPM problem to seed the solution of a related problem.&amp;nbsp; The net was that using a relatively simple warmstart procedure they were able to get (roughly) a factor of 3 speedup for their test set.&amp;nbsp; There were also some other IPM warmstart researchers in attendance - in particular &lt;A href="http://www.bilkent.edu.tr/~yildirim/" mce_href="http://www.bilkent.edu.tr/~yildirim/"&gt;Alper Yilidrim&lt;/A&gt; and &lt;A href="http://www.pages.drexel.edu/~hvb22/" mce_href="http://www.pages.drexel.edu/~hvb22/"&gt;Hande Benson&lt;/A&gt;. Alper had a great survey talk of existing IPM warmstart methods, and Hande is one of the top researchers in the area.&amp;nbsp; I am sure there have been interesting discussions this week!&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;STRONG&gt;&lt;A href="http://www.mosek.com/fileadmin/homepages/e.d.andersen/" mce_href="http://www.mosek.com/fileadmin/homepages/e.d.andersen/"&gt;Erling Andersen&lt;/A&gt; (&lt;A href="http://www.mosek.com/" mce_href="http://www.mosek.com"&gt;Mosek&lt;/A&gt;):&lt;/STRONG&gt; The afternoon IPM session had talks by Erling Andersen from Mosek, Jacek Gondzio, and myself.&amp;nbsp; Erling talked about SOCP improvements in MOSEK 6 (which will be out later this year).&amp;nbsp; He's had SOCP support forever, but for version 6 he has refactored and reworked much of the implementation.&amp;nbsp; He has run into problems getting high accuracy solutions (I feel his pain), and he has had some problems with infeasible or nearly infeasible problems.&amp;nbsp; He had some interesting thoughts on infeasibility criteria, rooted in his experience with real problems.&amp;nbsp; He's going to get about a 15% speedup, which is quite impressive since he is already starting with a very fast solver.&amp;nbsp; Erling has built a great set of solvers and I wish him well with Mosek 6. 
&lt;P&gt;&lt;STRONG&gt;&lt;A href="http://www.maths.ed.ac.uk/~gondzio/" mce_href="http://www.maths.ed.ac.uk/~gondzio/"&gt;Jacek Gondzio&lt;/A&gt;&lt;/STRONG&gt; talked about the use of indirect methods (such as preconditioned conjugate gradient) in IPM.&amp;nbsp; This hasn't worked out well in the past because such methods are not able to solve the systems to the accuracy required by IPM search directions.&amp;nbsp; And the problem is still not solved, but for his new approach he did show some impressive results for dense problems.&lt;BR&gt;&amp;nbsp;&lt;BR&gt;The title of &lt;STRONG&gt;my talk&lt;/STRONG&gt; was Interior Point Methods in Solver Foundation.&amp;nbsp; I gave an overview of where IPM sits in the Solver Foundation stack, discussed our user and solver models.&amp;nbsp; (And why different user and solver models are necessary - the "user model" serves Solver Foundation Services as well as programmers, whereas the solver model is structured so as to attain the most numerically stable, high performance solver possible.&amp;nbsp; Separation of concerns!)&amp;nbsp; Then I gave a high-level overview of our solution approach, and talked about a couple of implementation issues including handling of free variables, equality constraints, etc.&amp;nbsp; Lastly I talked about some numerical stability issues. I got nice feedback from people afterwards and there was a lot of curiosity about who is using our stuff and what is next.&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9887863" width="1" height="1"&gt;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="combinatorial optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx" /><category term="Solver Foundation" scheme="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="OML" scheme="http://blogs.msdn.com/natbr/archive/tags/OML/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /><category term="ISMP" scheme="http://blogs.msdn.com/natbr/archive/tags/ISMP/default.aspx" /><category term="interior point methods" scheme="http://blogs.msdn.com/natbr/archive/tags/interior+point+methods/default.aspx" /></entry><entry><title>Int'l Symposium on Mathematical Programming, Day 1</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/08/26/int-l-symposium-on-mathematical-programming-day-1.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/08/26/int-l-symposium-on-mathematical-programming-day-1.aspx</id><published>2009-08-26T16:35:00Z</published><updated>2009-08-26T16:35:00Z</updated><content type="html">&lt;P&gt;I am attending the &lt;A href="http://ismp2009.eecs.northwestern.edu/program.htm" target=_blank mce_href="http://ismp2009.eecs.northwestern.edu/program.htm"&gt;ISMP math programming conference&lt;/A&gt; in Chicago, representing the &lt;A href="http://www.solverfoundation.com/" target=_blank mce_href="http://www.solverfoundation.com"&gt;Solver Foundation&lt;/A&gt; team. Here are some of my impressions of Day 1 at ISMP:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Plenary [Steven Boyd]: &lt;/STRONG&gt;The plenary speaker was &lt;A href="http://www.stanford.edu/~boyd/" target=_blank mce_href="http://www.stanford.edu/~boyd/"&gt;Steve Boyd&lt;/A&gt; who talked about real-time embedded convex optimization.&amp;nbsp; He considered cases where problems need to be solved in milliseconds or less: control, signal processing, resource allocation, and even finance (think flash trading).&amp;nbsp;&amp;nbsp; The approach is basically to extend "disciplined convex programming".&amp;nbsp; DCP is a modeling system where problems are convex "by construction" because they combine operators with well-known properties; the system is then able to rewrite the problem in the standard form required by a convex programming solver (such as an IPM QP/SOCP solver). The new step is that the system can now generate highly optimized C code for a custom solver for the particular problem family described by the model.&amp;nbsp; (The algorithm itself is standard IPM.)&amp;nbsp; You can do all sorts of optimizations in this case: the problem structure is known so the symbolic ordering can be done in advance, you can ensure better memory locality, etc.&amp;nbsp; He gave many example where small QP instances were solved in tensof microseconds.&amp;nbsp; Fun stuff. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Morning Sessions:&lt;/STRONG&gt; I attended a morning session concerning approaches for nonconvex optimization problems. Jon Lee talked about solving a particular class of parametric nonlinear problems, &lt;A href="http://www.biz.uiowa.edu/faculty/anstreicher/" target=_blank mce_href="http://www.biz.uiowa.edu/faculty/anstreicher/"&gt;Kurt Anstreicher&lt;/A&gt; talked about *nonconvex* QP and associated bounds.&amp;nbsp; I then went to a straight-up theory session talking about convergence rates &amp;amp; asymptotic costs for IPM - there were a couple of new results and an interesting "corrector-predictor" (instead of the other way around) approach that attains better asymptotic convergence.&amp;nbsp; There is an embarrassment of riches at ISMP: I missed by John Hooker about integrating MIP, constraint &amp;amp; global optimization, a great MIP session including Bob Bixby from &lt;A href="http://blogs.msdn.com/controlpanel/blogs/www.gurobi.com" target=_blank mce_href="http://blogs.msdn.com/controlpanel/blogs/www.gurobi.com"&gt;Gurobi&lt;/A&gt;, and all sorts of other stuff.&amp;nbsp; There are a staggering number of good talks to attend.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Afternoon Sessions [Modeling / Stochastic]:&lt;/STRONG&gt; I went to a modeling languages track in the afternoon.&amp;nbsp; The first speaker was from &lt;A href="http://www.lindo.com/" target=_blank mce_href="http://www.lindo.com/"&gt;LINDO Systems&lt;/A&gt;&amp;nbsp;who talked about their new &lt;A href="http://www.lindo.com/index.php?option=com_content&amp;amp;view=article&amp;amp;id=2&amp;amp;Itemid=10" target=_blank mce_href="http://www.lindo.com/index.php?option=com_content&amp;amp;view=article&amp;amp;id=2&amp;amp;Itemid=10"&gt;LINGO&lt;/A&gt; offering.&amp;nbsp; The primary new feature is to support stochastic modeling. There were some screenshots from &lt;A href="http://www.lindo.com/index.php?option=com_content&amp;amp;view=article&amp;amp;id=3&amp;amp;Itemid=11" mce_href="http://www.lindo.com/index.php?option=com_content&amp;amp;view=article&amp;amp;id=3&amp;amp;Itemid=11"&gt;What's Best&lt;/A&gt;, their spreadsheet solver. They had a few nice samples as well.&lt;/P&gt;
&lt;P&gt;Gautam Mitra from &lt;A href="http://www.optirisk-systems.com/" mce_href="http://www.optirisk-systems.com/"&gt;OptiRisk&lt;/A&gt; was up next - he talked about SAMPL, stochastic extensions for AMPL.&amp;nbsp; They have extended SAMPL to support:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Chance constraints&lt;/LI&gt;
&lt;LI&gt;Integrated chance constraints&lt;/LI&gt;
&lt;LI&gt;Robust optimization&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Chance constraints are interesting - they occur in a range of financial problems including VaR and CVaR calculation.&amp;nbsp; Gautam riffed on the difference between stochastic and robust optimization by invoking Rumsfeld:&amp;nbsp; there are known knowns [deterministic optimization], known unknowns [stochastic],&amp;nbsp; and unknown unknowns [robust optimization].&amp;nbsp; In robust optimization you may have problem coefficients that are in some range with an unknown distribution and you want the constraints to hold in all (or most) possible circumstances.&amp;nbsp; Robust optimization also has SOCP reformulations, and I am a big believer because I think RO can be cleanly expressed in modeling languages.&amp;nbsp; The last talk in the session was about &lt;A href="http://control.ee.ethz.ch/~joloef/yalmip.php" target=_blank mce_href="http://control.ee.ethz.ch/~joloef/yalmip.php"&gt;YALMIP&lt;/A&gt; support for robust optimization - YALMIP has had widespread adoption by control theory specialists and has had a long history of improvements.&amp;nbsp; This talk was very code-oriented&amp;nbsp;and fun to watch.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;A few overall impressions: I think it is fair to say that SOCP is entering the mainstream with LP/QP/MIP - it came up a lot today.&amp;nbsp; On the modeling side, it was interesting to see that stochastic was featured in all three talks in the session I attended.&amp;nbsp; A larger trend is that MINLP (mixed integer nonlinear programming) is hot.&amp;nbsp; There are tons of tracks on it, and it is [unsurprisingly] being taken on by both the MIP and NLP communities.&amp;nbsp; The problem description is very general so of course there are applications, but the dust has not settled on the solver side.&amp;nbsp; &lt;BR&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9885312" width="1" height="1"&gt;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="combinatorial optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx" /><category term="Solver Foundation" scheme="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /><category term="ISMP" scheme="http://blogs.msdn.com/natbr/archive/tags/ISMP/default.aspx" /></entry><entry><title>Quadratic Assignment Problems: solution enumeration</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/07/27/quadratic-assignment-problems-solution-enumeration.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/07/27/quadratic-assignment-problems-solution-enumeration.aspx</id><published>2009-07-27T19:53:00Z</published><updated>2009-07-27T19:53:00Z</updated><content type="html">&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;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx" /><category term="QAP" scheme="http://blogs.msdn.com/natbr/archive/tags/QAP/default.aspx" /><category term="combinatorial optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /></entry><entry><title>Quadratic Assignment Problems: strong and weak branching</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/07/19/quadratic-assignment-problems-strong-and-weak-branching.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/07/19/quadratic-assignment-problems-strong-and-weak-branching.aspx</id><published>2009-07-20T05:19:00Z</published><updated>2009-07-20T05:19:00Z</updated><content type="html">&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;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx" /><category term="QAP" scheme="http://blogs.msdn.com/natbr/archive/tags/QAP/default.aspx" /><category term="combinatorial optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="operations research" scheme="http://blogs.msdn.com/natbr/archive/tags/operations+research/default.aspx" /></entry><entry><title>Quadratic assignment problems: branching</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/07/12/quadratic-assignment-problems-branching.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/07/12/quadratic-assignment-problems-branching.aspx</id><published>2009-07-13T02:24:00Z</published><updated>2009-07-13T02:24:00Z</updated><content type="html">&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;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx" /><category term="QAP" scheme="http://blogs.msdn.com/natbr/archive/tags/QAP/default.aspx" /><category term="combinatorial optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/combinatorial+optimization/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /></entry><entry><title>Solver Foundation LINQ to SQL example</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/natbr/archive/2009/06/02/solver-foundation-linq-to-sql-example.aspx" /><id>http://blogs.msdn.com/natbr/archive/2009/06/02/solver-foundation-linq-to-sql-example.aspx</id><published>2009-06-02T17:45:00Z</published><updated>2009-06-02T17:45:00Z</updated><content type="html">&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;</content><author><name>Nathan Brixius</name><uri>http://blogs.msdn.com/members/Nathan+Brixius.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/natbr/archive/tags/C_2300_/default.aspx" /><category term="Solver Foundation" scheme="http://blogs.msdn.com/natbr/archive/tags/Solver+Foundation/default.aspx" /><category term="optimization" scheme="http://blogs.msdn.com/natbr/archive/tags/optimization/default.aspx" /><category term="LINQ" scheme="http://blogs.msdn.com/natbr/archive/tags/LINQ/default.aspx" /><category term="OML" scheme="http://blogs.msdn.com/natbr/archive/tags/OML/default.aspx" /><category term="SQL" scheme="http://blogs.msdn.com/natbr/archive/tags/SQL/default.aspx" /></entry></feed>