Solver Foundation provides an easytouse and flexible plugin infrastructure as an addition to its already rich set of solvers. Users can choose their favorite plugin solvers to solve the model, and yet leverage all features provided in Solver Foundation Services (SFS).
The key process is to register the plugin solvers via an app.config file. A typical config file looks as follows:
<?xml version="1.0" encoding="utf8" ?> <configuration> <configSections> <section name="MsfConfig" type="Microsoft.SolverFoundation.Services.MsfConfigSection, Microsoft.Solver.Foundation, Version=2.0.2.8632, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowLocation="true" allowDefinition="Everywhere" allowExeDefinition="MachineToApplication" restartOnExternalChanges="true" requirePermission="true" /> </configSections> <MsfConfig> <MsfPluginSolvers> <MsfPluginSolver capability="<plugin solver capability>" assembly="<path\to\your\plugin\solver\dll" solverclass="<plugin solver class name>" directiveclass="<plugin solver directive class name>" parameterclass="<plugin solver parameter class name>"/> </MsfPluginSolvers> </MsfConfig> </configuration> 
The information such as assembly name and solver class name can usually be found from the plugin solver provider.
The config file then will coexist with the compiled exe file of the user app. When, inside the app code, a Solve call is issued, SFS will pick a solver based on the model kind, directive instances passed in, and the solver registration.
The app code in this case can be written in any .NET compliant language such as C# or VB.NET.
IronPython is “an implementation of the Python programming language running under .NET …” So it is possible to use Solver Foundation, and with plugin solvers, in IronPython code. However, one difficulty is that Python is an interpreted language. Therefore we cannot compile Python code to an exe file. So how do we register our plugin solvers?
The trick is to register the plugin solvers inside ipy.exe.config (or ipy64.exe.config). These two files must be put under the same folder with ipy.exe and ipy64.exe. We assume IronPython 2.6 RC2 in the following discussion.
There is IronPython sample code under <your document folder>\Microsoft Solver Foundation\Samples\SolverFoundationServices\IronPython if we install Solver Foundation v2.0. We will use the petrochemsfs.py as the example. Let us again use Gurobi solver as our plugin solver. Gurobi solver dlls are installed by default under C:\Program Files\Microsoft Solver Foundation\2.0.2.8632\Plugins (and C:\Program Files\Microsoft Solver Foundation\2.0.2.8632\Plugins(x86) if the target platform is 64bit). So the plugin solver registration looks as follows:
ipy.exe.config 
<?xml version="1.0" encoding="utf8" ?> <configuration> <configSections> <section name="MsfConfig" type="Microsoft.SolverFoundation.Services.MsfConfigSection, Microsoft.Solver.Foundation, Version=2.0.2.8632, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowLocation="true" allowDefinition="Everywhere" allowExeDefinition="MachineToApplication" restartOnExternalChanges="true" requirePermission="true" /> </configSections> <MsfConfig> <MsfPluginSolvers> <MsfPluginSolver capability="LP" assembly="C:\Program Files\Microsoft Solver Foundation\2.0.2.8632\Plugins(x86)\GurobiPlugin.dll" solverclass="SolverFoundation.Plugin.Gurobi.GurobiSolver" directiveclass="SolverFoundation.Plugin.Gurobi.GurobiDirective" parameterclass="SolverFoundation.Plugin.Gurobi.GurobiParams"/> </MsfPluginSolvers> </MsfConfig> </configuration> 
ipy64.exe.config 
<?xml version="1.0" encoding="utf8" ?> <configuration> <configSections> <section name="MsfConfig" type="Microsoft.SolverFoundation.Services.MsfConfigSection, Microsoft.Solver.Foundation, Version=2.0.2.8632, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowLocation="true" allowDefinition="Everywhere" allowExeDefinition="MachineToApplication" restartOnExternalChanges="true" requirePermission="true" /> </configSections> <MsfConfig> <MsfPluginSolvers> <MsfPluginSolver capability="LP" assembly="C:\Program Files\Microsoft Solver Foundation\2.0.2.8632\Plugins\GurobiPlugin.dll" solverclass="SolverFoundation.Plugin.Gurobi.GurobiSolver" directiveclass="SolverFoundation.Plugin.Gurobi.GurobiDirective" parameterclass="SolverFoundation.Plugin.Gurobi.GurobiParams"/> </MsfPluginSolvers> </MsfConfig> </configuration> 
Now if we run the petrochemsfs.py sample (ipy O petrochemsfs.py), we will see that Gurobi solver is used:
Solver Foundation supports flexible data binding so that the algebraic model can be separated from the data source. In Solver Foundation, both parameters and decisions can be bound to data source. It makes writing and maintaining models really easy.
To bind a parameter to a data source, we usually need to specify the data source, the value field, and indexes. For example, the following parameter WarehouseCap is bound to the table that has two columns.
The table looks as follows.
warehouse 
capacity 
1 
10 
2 
29 
3 
13 
Column warehouse is the index column/field, and column capacity is the value column/field.
In C#, the binding can be set via the following line.
_model.WarehouseCap.SetBinding(warehouseCaps, "Capacity", "Warehouse");
assuming warehouseCaps is an IEnumerable that contains the data.
The sparse data case is where the table contains multiple index columns and not all the combinations of the index values exist in the table. For example, there could be a table that records the cost of shipping goods from warehouses to stores. However, it is usually not the case that every warehouse can ship goods and every store. For example,
warehouse 
store 
cost 
1 
2 
100 
2 
3 
200 
3 
1 
150 
Such table represents input data that are sparse. By default, the missing rows all have the value column being zero.
Currently in Solver Foundation v2.0, we cannot bind to such sparse data directly. However, we observe that the values appearing in an index column of the sparse table form a subset of the values allowed for that index column. Furthermore, Solver Foundation allows parameters to appear as the indexes to other parameters or decisions. We can use the following approach to bind to this sparse table.
Let us introduce a helper column called costid into the table.
costid 
warehouse 
store 
cost 
0 
1 
2 
100 
1 
2 
3 
200 
2 
3 
1 
150 
Now we create two extra parameters called CostWarehouse and CostStore, which will be bound to the warehouse column and store column respectively. The needed parameter Cost will be bound to the cost column as we expected. All three parameters now use costid as the index.
Here are the actual definitions for the three parameters.
Parameters[ Sets[Any], costid ], Parameters[ Integers[0, Infinity], CostWarehouse[costid], CostStore[costid] ], Parameters[ Reals[Infinity, Infinity], Cost[costid] ], 
Assume we have a decision called Ship defined as follows.
Parameters[ Sets[Any], warehouse, store ], Decisions[ Integers[0, 1], Ship[warehouse, store] ], 
Ship[w, s] being 1 if and only if we want to ship goods from warehouse w to store s.
Now suppose we want to construct as constraint that says “the total cost of shipping is between 100 and 400. The constraint can be written as follows.
100 <= Sum[{id, costid}, Cost[id] * Ship[CostWarehouse[id], CostStore[id]]] <= 400 
Notice that we iterate through all rows in the cost table and use parameter CostWarehouse[id] and CostStore[id] as indexes on decision Ship.
To ensure that we do not ship any goods from incompatible warehouse and store pairs, we add the following constraint using the fact that default values are zero:
Foreach[{w, warehouse}, {s, store}, Ship[w, s] <= Sum[{id, costid}, AsInt[CostWarehouse[id] == w & CostStore[id] == s]] 
We leave it to the reader to figure out how this constraint works. Notice that, in the last constraint, the complicated righthand side of the inequality actually is reduced to a constant value. So the model is still a MILP model.
Here is the complete model.
Model[ Parameters[ Sets[Integers[0, Infinity]], costid, warehouse, store ], Parameters[ Integers[0, Infinity], CostWarehouse[costid], CostStore[costid] ], Parameters[ Reals[Infinity, Infinity], Cost[costid], WarehouseCap[warehouse], StoreCap[store] ], Decisions[ Integers[0, 1], Ship[warehouse, store] ], Constraints[ Constraint1 > 100 <= Sum[{id, costid}, Cost[id] * Ship[CostWarehouse[id], CostStore[id]]] <= 400, Constraint2 > Foreach[{w, warehouse}, {s, store}, Ship[w, s] <= Sum[{id, costid}, AsInt[CostWarehouse[id] == w & CostStore[id] == s]]] ], Goals[ Maximize[ Goal1 > Annotation[Sum[{w, warehouse}, {s, store}, Ship[w, s]], "order", 0] ] ] ] 
Here is a sample run.
[11/2/2009 10:54:59 PM] Solve started... [11/2/2009 10:55:00 PM] ===Solver Foundation Service Report=== Datetime: 11/2/2009 10:55:00 PM Model Name: Default Capabilities Requested: MILP Solve Time (ms): 34 Total Time (ms): 187 Solve Completion Status: Optimal Solver Selected: SolverFoundation.Plugin.Gurobi.GurobiSolver Algorithm: Dual Arithmetic: Double Variables: 9 > 20 + 11 Rows: 11 > 11 Nonzeros: 21 Eliminated Slack Variables: 0 Pricing (double): Automatic Pivot Count: 0 Phase 1 Pivots: 1 + 0 Phase 2 Pivots: 1 + 0 Factorings: 1 + 0 Degenerate Pivots: 1 (0.00 %) Branches: 0 ===Solution Details=== Goals: Goal1: 2 Decisions: Ship(1, 2): 1 Ship(2, 3): 1 Ship(3, 1): 0 Ship(1, 1): 0 Ship(1, 3): 0 Ship(2, 1): 0 Ship(2, 2): 0 Ship(3, 2): 0 Ship(3, 3): 0 [11/2/2009 10:55:00 PM] Solve Complete 
DeploytoC# is a new feature we shipped in Solver Foundation v2.0 Excel Addin. The idea is to simplify the process of deploying an OML model written in the Addin into a Visual Studio project that builds the same model using Solver Foundation Services APIs. With this new feature, users who are comfortable in writing and debugging their models in Excel/OML environment now can produce an equivalent C# model by a click of a button. Once the C# model is generated, users can further embed the model code into their applications. It is also possible now to solve the model using multiple directives or use plugin solvers.
In this post, we will show how to use the Deploy functionality to convert an OML model into a Visual Studio project. To repeat the following steps yourself, please make sure you have Microsoft Office 2007, Visual Studio 2008, and Solver Foundation v2.0 installed. Furthermore, to try out the plugin solver you have, please update the solver registration section in the config file accordingly.
In Solver Foundation v2.0 release, we include a sample on the supply chain planning. It can be found under <your documents folder>\Microsoft Solver Foundation\Samples\Excel\LP. Let us start with this sample.
Once we load this Excel file, we can see the data are stored in the spreadsheet and the OML model is presented in our new modeling pane.
We can solve the model in Excel by clicking the Solve button. Here is the result.
As we can see from the log, Solver Foundation simplex solver is used with the default setting to solve this model.
Now let us start deploying the model into C#. We notice the new Deploy button in the Ribbon.
Let us click on it. The following window pops up, where we can specify the C# file name for the model to be deployed. Let's call it SupplyChainPlanning.cs.
Now we have two files created under the target folder: SupplyChainPlanning.cs and SupplyChainPlanning.xml. The first file contains the equivalent model written in C# and the second xml file contains the data from the spreadsheet. The model now can be embedded into any Visual Studio C# project.
Let us now open Visual Studio 2008 and create a new C# console project. Notice that Solver Foundation v2.0 installation creates two project templates in Visual Studio 2008. Let us pick the Solver Foundation Console Application template.
After the project is created, let us add the SupplyChainPlanning.cs and SupplyChainPlanning.xml into the project. We can delete the sample model file created automatically by the template because we are not going to use it. We make sure that the xml file will be always copied to the output directory during compilation since it contains the data we need.
Next, we need to write some glue code to bind the data from XML file to the model. This part is not automatically done at this moment. However, the data binding code is pretty straightforward. We use LINQ to XML in this case.
class Program { private ExportedModel _model; public Program() { _model = new ExportedModel(); } public void Run() { BindData(); var solution = _model.Context.Solve(); Console.WriteLine(solution.GetReport().ToString()); } private void BindData() { var data = XElement.Load("SupplyChainPlanning.xml"); var manufactureLoads = from load in data.Descendants("manufactureLoads") select new { Product = load.Element("Product").Value, Load = Convert.ToDouble(load.Element("ManufactureLoads").Value) }; var factoryCapacities = from cap in data.Descendants("factoryCapacity") select new { Factory = cap.Element("Factory").Value, Capacity = Convert.ToDouble(cap.Element("FactoryCapacity").Value) }; var unitManufactureCosts = from cost in data.Descendants("unitManufactureCost") select new { Product = cost.Element("Product").Value, Cost = Convert.ToDouble(cost.Element("UnitManufactureCost").Value) }; var transports = from tran in data.Descendants("transport") select new { Product = tran.Element("Product").Value, Area = tran.Element("Geography").Value, Factory = tran.Element("Factory").Value, Transport = Convert.ToDouble(tran.Element("Transport").Value) }; var demandForecastPrices = from demand in data.Descendants("demandForecastPrice") where demand.Elements().Count() == 4 select new { Product = demand.Element("Product").Value, Area = demand.Element("Geography").Value, Promotion = demand.Element("Promotion").Value, Price = Convert.ToDouble(demand.Element("demandForecastPrice").Value) }; var demandForecastUnits = from demand in data.Descendants("demandForecastUnits") where demand.Elements().Count() == 4 select new { Product = demand.Element("Product").Value, Area = demand.Element("Geography").Value, Promotion = demand.Element("Promotion").Value, Units = Convert.ToDouble(demand.Element("demandForecastUnits").Value) }; _model.manufactureLoads.SetBinding(manufactureLoads, "Load", "Product"); _model.factoryCapacity.SetBinding(factoryCapacities, "Capacity", "Factory"); _model.unitManufactureCost.SetBinding(unitManufactureCosts, "Cost", "Product"); _model.transport.SetBinding(transports, "Transport", "Product", "Area", "Factory"); _model.demandForecastPrice.SetBinding(demandForecastPrices, "Price", "Product", "Area", "Promotion"); _model.demandForecastUnits.SetBinding(demandForecastUnits, "Units", "Product", "Area", "Promotion"); } static void Main(string[] args) { var program = new Program(); program.Run(); } } 
Note that we have a where clause in building demandForecastPrices and demandForecastUnits. We leave to the readers to experiment why the where clause is needed.
Now let's run the console app. Here is the output. For simplicity, we skip the decision values. We can verify that the objective function value is the same as we have seen in Excel.
===Solver Foundation Service Report=== Datetime: 10/30/2009 12:03:57 Model Name: Default Capabilities Requested: LP Solve Time (ms): 515 Total Time (ms): 911 Solve Completion Status: Optimal Solver Selected: Microsoft.SolverFoundation.Solvers.SimplexSolver Directives: Microsoft.SolverFoundation.Services.Directive Algorithm: Primal Arithmetic: Hybrid Variables: 154 > 154 + 77 Rows: 104 > 77 Nonzeros: 416 Eliminated Slack Variables: 0 Pricing (exact): SteepestEdge Pricing (double): SteepestEdge Basis: Slack Pivot Count: 114 Phase 1 Pivots: 0 + 0 Phase 2 Pivots: 114 + 0 Factorings: 6 + 1 Degenerate Pivots: 82 (71.93 %) Branches: 0 ===Solution Details=== Goals: Profit: 9158191.66666667

Now to illustrate a more advance usage of Solver Foundation in this C# project, let's include a solver registration and use a plugin solver to solve it.
To use a plugin solver with Solver Foundation, please make sure you have all the needed DLLs from the plugin solver vendor. In this example, we will use Gurobi solver to solve this LP model.
First we need to add a config file to the project so that we can register the plugin solvers. Here is what the app.config file looks like
<?xml version="1.0" encoding="utf8" ?> <configuration> <configSections> <section name="MsfConfig" type="Microsoft.SolverFoundation.Services.MsfConfigSection, Microsoft.Solver.Foundation, Version=2.0.2.8632, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowLocation="true" allowDefinition="Everywhere" allowExeDefinition="MachineToApplication" restartOnExternalChanges="true" requirePermission="true" /> </configSections> <MsfConfig> <MsfPluginSolvers> <MsfPluginSolver capability="LP" assembly="GurobiPlugin.dll" solverclass="SolverFoundation.Plugin.Gurobi.GurobiSolver" directiveclass="SolverFoundation.Plugin.Gurobi.GurobiDirective" parameterclass="SolverFoundation.Plugin.Gurobi.GurobiParams"/> </MsfPluginSolvers> </MsfConfig> </configuration> 
Notice that we register Gurobi solver as an LP solver here, with Gurobi solver's class, directive class, and parameter class names.
Next, we need to include necessary DLLs into the project so that Solver Foundation can find them. Here is what the project looks like now.
Here we reference GurobiPlugin.dll (plugin solver wrapper) and add the gurobi20.dll (unmanaged code DLL for the actual solver) to the project. Notice that we set the "Copy to Output Directory" property of gurobi20.dll to "Copy Always" too. These two DLLs are shipped with Solver Foundation v2.0 and can be found under <your program files folder>\ Microsoft Solver Foundation\2.0.2.8632\Plugins.
Now let's run the application again. This time, we will see from the report that Gurobi solver is used and the same objective function value is returned.
===Solver Foundation Service Report=== Datetime: 10/30/2009 13:48:28 Model Name: Default Capabilities Requested: LP Solve Time (ms): 110 Total Time (ms): 522 Solve Completion Status: Optimal Solver Selected: SolverFoundation.Plugin.Gurobi.GurobiSolver Directives: Microsoft.SolverFoundation.Services.Directive Algorithm: Dual Arithmetic: Double Variables: 154 > 258 + 104 Rows: 104 > 104 Nonzeros: 416 Eliminated Slack Variables: 0 Pricing (double): Automatic Pivot Count: 36 Phase 1 Pivots: 1 + 0 Phase 2 Pivots: 1 + 0 Factorings: 1 + 0 Degenerate Pivots: 1 (2.78 %) Branches: 0 ===Solution Details=== Goals: Profit: 9158191.66666666 
To tweak the settings of Gurobi solver, we can further create a Gurobi solver directive and change the settings there. Then we pass the directive instance into Solve call. I will leave this to the readers to experiment.
This sample goes through all steps in deploying an OML model from Excel to Visual Studio. I hope it helps in your application development. Thank you for your time.
Lengning
]]>http://research.microsoft.com/enus/um/cambridge/projects/fsharp/default.aspx
The F# ODSL and SFS wrapper included in Solver Foundation v2.0 utilize the new feature, unit of measure, in F# to facilitate more robust modeling experience. In order to try out the sample, you will need to download the most recent update of F#, v1.9.7.8, from the link above.
Have fun!
]]>We are pleased to announce the release of Solver Foundation v2.0. This is the fourth ontime commercial release for the product. The Express edition is available now at http://code.msdn.microsoft.com/solverfoundation. The Standard Edition of Solver Foundation v2.0 has releasedtomanufacturing, and will be available online via MSDN subscriber downloads the week of 11oct09, and offline worldwide via MSDN in approximately two months later. Our Enterprise edition is also available.
In version 2, we focused on growing our collection of solvers, vastly improving our tooling experience, and introduced the beginnings of what will be our simulation framework. At a high level, Solver Foundation v2.0 has the following new features:
Top level features we are introducing in Version 2.0:
 Design Tools. We have improved the integration, interchange, and workflow of our design surfaces for Excel, SharePoint, and Visual Studio – modelers will now be able to take models algorithmically designed in Excel and inject this directly into a fullfledged Visual Studio/C# solutions with the press of a “deploy” button. Additionally, a model can be sent directly to SharePoint using our scriptsafe OMLX format. This is a longterm focus area to make modeling as easy as possible without losing any capabilities for the advanced user.
 Solver Foundation Services
· Stochastic Programming and Optimization with Monte Carlo simulation capabilities. The SFS supports random parameters and recourse decisions, allowing for the definition and solution of twostage stochastic models
· Submodels. Our master model can now define and reference submodels, allowing for better encapsulation and reuse
· Special Ordered Sets. Introduced SOS1 and increased flexibility in the definition of SOS2 constraints
· Solver Plugin SDK improvements to include Special Ordered Sets, more detailed reporting (e.g., IIS), and expanded our solver partner ecosystem to include LINDO Systems
 Solvers
· Gurobi version 2.0 Solver is included in our release, and is the default Solver Foundation MIP solver
· Second Order Conic Programming (SOCP) Solver Extensions to our IPM Solver to support rich constraint modeling (we can now have nonlinear goals and constraints)
· Extensions to the Simplex Solver to support SOS1 and SOS2 modeling and solving
· Improved our inhouse Mixed Integer Programming Solver
· Metaheuristics and Global Constraints for our Constraint Solver (developed in conjunction with our friends at MSR Cambridge) to ease and simplify declarative modeling with more powerful constructs
 Created a new F# Optimization DSL (ODSL) that incorporates unitsofmeasure work from MSR Cambridge
 Increased our solver vendor and modeling partner ecosystem to include LKINDO Systems and Princeton Consultants – more information can be found at www.solverfoundation.com
 Our core DLL is now localized in German. This is the start of our longer term focus to localize all of Solver Foundation in the top languages worldwide
 A host of other improvements
In Solver Foundation CTP release, we shipped an optimization domain specific language (ODSL) in F#, which embedded Solver Foundation simplex solver for solving linear programming models. In the upcoming version 2 release, we will ship an enhanced version of this ODSL. Here are some of the highlights:
· Units of measure: in F# numerical quantities can be annotated by a unit such as kilogram, dollar per day. These annotations not only provide additional and explicit documentation on the nature of the quantities involved, but also allow F# to statically check that no mistake is made in the use of these quantities: adding Watt and Newton is incorrect for example.
Units of measures in F# are declared as follows:
[<Measure>] type Dollar [<Measure>] type Barrel [<Measure>] type Day [<Measure>] type ProductionRate = Barrel/Day 
The syntax for annotating a numerical value with its measure is shown below:
let dailyOutput = 9000.0<Barrel/Day> let price = 140.0<Dollar/Barrel> let dailyCost = dailyOutput * price 
In our new ODSL, units of measures can be used in modeling a problem, which help modelers to catch errors in the model where incompatible quantities are used in the constraints or goal functions. Here is a simple example of the Petrochem problem.
let a = 20.0<Dollar/Barrel> let b = 15.0<Dollar/Barrel> let sa = var<Barrel/Day>() let vz = var<_>() minimise (a * sa + b * vz) where [ 0.3 * sa + 0.4 * vz >= 2000.<_>; 0.4 * sa + 0.2 * vz >= 1500.<_>; 0.2 * sa + 0.3 * vz >= 500.<_>; sa <= 9000.<_>; vz <= 6000.<_>; sa >= 0.<_>; vz >= 0.<_> ] 
Note that if quantities such as a were defined to have a measure other than Dollar/Barrel, F# would have caught the error in the goal function where b*vz had the measure Dollar/Day while a*sa did not.
· Solver Foundation wrapper in F#: this wrapper directly wraps Solver Foundation APIs and does not use F# quotations. With this wrapper, we also enabled units of measure in models that are written against Solver Foundation APIs. Here is the model of the same Petrochem problem written in this wrapper:
[<Measure>] type Dollar [<Measure>] type Barrel [<Measure>] type Day [<Measure>] type ProductionRate = Barrel/Day // Initialization of the SFS model from the context // We use the SfsModel class that wraps the usual SFS Model class // and additionally keeps track of the F#specific type information let context = SolverContext.GetContext() let petrochem = new SfsModel(context) /// Optimization variable: Production in SaudiArabia let buyfromSA = petrochem.CreateRealVariable<ProductionRate>() /// Optimization variable: Production in Venezuela let buyfromVZ = petrochem.CreateRealVariable<ProductionRate>()
// Add the production constraints: // How much of gasoline, jet fuel and machine lubricants can // we refine from the oil provided by the two supplier countries? let c1 = petrochem.AddConstraint ( 0.3*buyfromSA + 0.4*buyfromVZ >>== 2000.0<Barrel/Day>) let c2 = petrochem.AddConstraint ( 0.4*buyfromSA + 0.2*buyfromVZ >>== 1500.0<Barrel/Day>) let c3 = petrochem.AddConstraint ( 0.2*buyfromSA + 0.3*buyfromVZ >>== 500.0<Barrel/Day>) /// Maximum production in SaudiArabia let maxProductionSA = 9000.0<_> /// Maximum production in Venezuela let maxProductionVZ = 6000.0<_> // Add the maximum production constraints to the model petrochem.AddConstraints [ 0.0<_> <<== buyfromVZ; buyfromVZ <<== maxProductionVZ; 0.0<_> <<== buyfromSA ; buyfromSA <<== maxProductionSA ] /// Business goal: minimize the running costs let runningCost = petrochem.AddGoal (GoalKind.Minimize, 20.0<Dollar/Barrel>*buyfromSA + 15.0<Dollar/Barrel>*buyfromVZ) /// Solution to the petrochem example let petrochemSolution = petrochem.Solve() 
The ODSL and the wrapper source code will be shipped in Solver Foundation version 2 as a sample on how to enable F# to solve optimization problems. More details will be available in the release doc. The essence here is that, being a complete .NET solution and CLS compliant, Solver Foundation can be easily embedded in other .NET environments to help our customers to solve their problems in the environment that they are most familiar with.
Version 2 of Solver Foundation contains a number of new features and enhancements. Please also check out Nathan’s blog on simulation and stochastic programming. For more information, please stay tuned for the actual release.
Lengning
]]>Please check out www.solverfoundation.com for an immediate access to our Express edition. Standard edition will be ready through MSDN subscription in the following days.
It's really exciting to see three releases in five months.
 Lengning
]]>http://www.solverfoundation.com
Official website of Solver Foundation.
]]>Here is a post that describes a recent use case of Microsoft Solver Foundation in real world applications.
Thank you Pascal for contacting us with the problem and collaborating with us to get the work done in time. It was great fun for us working with you.
]]>