Solving the model
Prerequisites
Get the solution
When a model is solved, the solution is usually copied into the business layer of the application. Some reporting or evaluation steps might be processed at this time.
In this example, we will copy the solution values back into the model's variables and print them on the screen.
A few lines have been inserted into the Program.cs right after the line solver.Solve()
-call. They
- Copy the Solution's values back into the VariableCollections' Variables.
Print the objective and the decision values on the screen.
// use default settings var scopeSettings = new OptimizationConfigSection(); scopeSettings.ModelElement.EnableFullNames = true; using (var scope = new ModelScope(scopeSettings)) { // 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}")); } }
Note: A Console.ReadKey()
at the end of the program might help reading the output on the screen.
The resulting output
For better understanding we visualized the output below. The NDP is optimal, when Beijing, Paderborn and New York are connected. As well as San Francisco and São Paulo.
Notes:
- This output is taken from the program's console. OPTANO.Modeling prints the section from beginning to
Best objective
. You can redirect the default Output to other Streams. - The variable names get some extension (like _A, _AQ). These extensions are the variable short names. By setting
scopeConfig.NameHandling = NameHandlingStyle.UniqueLongNames
, OPTANO.Modeling will keep the long names as well, to support your debug activity. When running the model in production, usescopeConfig.NameHandling = NameHandlingStyle.UniqueShortNames
to save memory and cpu time.
The output will look like this:
Optimizing the Model...
Optimize a model with 22 rows, 12 columns and 48 nonzeros
Coefficient statistics:
Matrix range [7e-03, 1e+00]
Objective range [1e+00, 2e+04]
Bounds range [1e+00, 8e+01]
RHS range [5e+01, 1e+02]
Found heuristic solution: objective 24750
Presolve removed 22 rows and 12 columns
Presolve time: 0.00s
Presolve: All rows and columns removed
Explored 0 nodes (0 simplex iterations) in 0.14 seconds
Thread count was 1 (of 4 available processors)
Optimal solution found (tolerance 0.00e+00)
Best objective 2.475000000000e+04, best bound 2.475000000000e+04, gap 0.0%
[sum of all cost, 24750]
Flow Paderborn to New York_B : 100
Flow Paderborn to São Paulo_C : 0
Flow Beijing to Paderborn_D : 50
Flow New York to Beijing_E : 0
Flow Beijing to São Paulo_F : 0
Flow São Paulo to San Francisco_G : 50
Design Paderborn to New York_H : 1
Design New York to Beijing_I : 0
Design Beijing to São Paulo_J : 0
Design São Paulo to San Francisco_K : 1
Design Paderborn to São Paulo_L : 0
Design Beijing to Paderborn_M : 1
Next steps
- The solver reduced the model. Learn how OPTANO.Modeling supports developers to keep models small. > Presolve removed Columns and rows
- Default settings not appropriate? Change them in ModelScope's Configuration
- Interested in more Models?