Solving the model
Prerequisites
Create Method to solve the model
This step will introduce a simple model runner.
- first of all, the data of the model will be created and stored into the list of nodes and edges.
- A OPTANO.Modeling.Optimization.Configuration is used to populate a ModelScope (the configuration of OPTANO.Model)
- the actual Model is generated from the data, the OPTANO.Modeling.Optimization.Configuration may affect the model generation, f.e. by the parameter EnableFullNames (default: @false), which might save memory and shorten all Names.
- A OPTANO.Modeling.Optimization.Solver in instanciated and used to solve the model. Solve returns a Solution, describing the solution status and the resulting variable values (decisions).
- Note: It is advised to put a
using
-block around theSolver
object. That way, the program will automatically release resources, such as license tokens, that are allocated by the solver, once theusing
-block is left.
- Note: It is advised to put a
- the solution values are copied into the model (business layer).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OPTANO.Modeling.Optimization.Solver.Gurobi810;
namespace NDP
{
using OPTANO.Modeling.Common;
using OPTANO.Modeling.Optimization;
using OPTANO.Modeling.Optimization.Configuration;
using OPTANO.Modeling.Optimization.Solver.Gurobi810;
/// <summary>
/// Demo program solving a network design problem
/// </summary>
class Program
{
/// <summary>
/// The main method
/// </summary>
/// <param name="args">
/// no arguments required
/// </param>
static void Main(string[] args)
{
// create example Nodes
INode pb = new Node("Paderborn", 50);
INode ny = new Node("New York", -100);
INode b = new Node("Beijing", 50);
INode sp = new Node("São Paulo", 50);
INode sf = new Node("San Francisco", -50);
// assign these nodes to a list of INodes
var nodes = new List<INode> { pb, ny, b, sp, sf };
// create example Edges
IEdge one = new Edge(ny, pb, null, 3, 6100);
IEdge two = new Edge(b, ny, null, 2, 11000);
IEdge three = new Edge(sp, b, 75, 1, 17600);
IEdge four = new Edge(sf, sp, null, 4, 10500);
IEdge five = new Edge(sp, pb, null, 5, 9900);
IEdge six = new Edge(pb, b, 50, 1, 7600);
// assign these edges to a list of IEdges
var edges = new List<IEdge> { one, two, three, four, five, six };
// Use long names for easier debugging/model understanding.
var config = new Configuration();
config.NameHandling = NameHandlingStyle.UniqueLongNames;
config.ComputeRemovedVariables = true;
using (var scope = new ModelScope(config))
{
// create a model, based on given data and the model scope
var designModel = new NetworkDesignModel(nodes, edges);
// Get a solver instance, change your solver
using (var solver = new GurobiSolver())
{
// solve the model
var solution = solver.Solve(designModel.Model);
// import the results back into the model
designModel.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues));
// print objective and variable decisions
Console.WriteLine($"{solution.ObjectiveValues.Single()}");
designModel.x.Variables.ForEach(x => Console.WriteLine($"{x.ToString().PadRight(36)}: {x.Value}"));
designModel.y.Variables.ForEach(y => Console.WriteLine($"{y.ToString().PadRight(36)}: {y.Value}"));
designModel.Model.VariableStatistics.WriteCSV(AppDomain.CurrentDomain.BaseDirectory);
Console.ReadLine();
}
}
}
}
}
Next step
Go to Get the solution