Business Objects & Instantiation
Visualization
The image below visualizes the data created below. In this example we have eight periods, for which the demand, setup cost per period, production cost per product, inventory cost per product and the production capacity per period are known. The production amount and inventory amount have to be determined by the solver according to the constraints in the model we will define in the following step.
PeriodInformation (Business Object)
Each PeriodInformation holds all relevant information. This includes the demand in the period, the inventory-, setup- and production costs as well as the maximum lot size.
PeriodInformation.cs
using System;
namespace MIP_CLSP
{
/// <summary>
/// A time step of the Capacitated Lot-Sizing Model
/// </summary>
public class PeriodInformation
{
/// <summary>
/// Gets the name of this time step
/// </summary>
public int Period { get; set; }
/// <summary>
/// Gets the demand in this time step
/// </summary>
public double Demand { get; set; }
/// <summary>
/// Gets the cost to setup the machine in this time step
/// </summary>
public double SetupCost { get; set; }
/// <summary>
/// Gets the cost to produce a single good in this time step
/// </summary>
public double ProductionCost { get; set; }
/// <summary>
/// Gets the inventory cost in this time step
/// </summary>
public double InventoryCost { get; set; }
/// <summary>
/// Production capacity in the time step
/// </summary>
public double Capacity { get; set; }
/// <summary>
/// Name of the time step
/// </summary>
/// <returns>
/// The name of this time step (<see cref="string"/>).
/// </returns>
public override string ToString() => Convert.ToString(Period);
}
}
In this example we are using a CsvReader package to read the data from timesteps.csv.
Period;Demand;SetupCost;ProductionCost;InventoryCost;Capacity
1;0;90;10;10;20
2;10;20;10;20;20
3;25;20;30;30;30
4;15;20;20;40;20
5;10;20;30;30;25
6;5;20;40;20;20
7;50;5;20;30;15
8;10;50;20;30;15
Program instance
Instantiation of the different PeriodInformation, the Model, as well as the Solver and an empty Solution.
Program.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CsvHelper;
using MIP_CLSP;
using OPTANO.Modeling.Optimization.Solver;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
namespace CLSP
{
using OPTANO.Modeling.Common;
using OPTANO.Modeling.Optimization;
using OPTANO.Modeling.Optimization.Configuration;
using OPTANO.Modeling.Optimization.Solver.Gurobi810;
/// <summary>
/// Demo program solving a Capacitated Lot-Sizing Problem
/// </summary>
class Program
{
/// <summary>
/// The main method
/// </summary>
/// <param name="args">
/// no arguments required
/// </param>
static void Main(string[] args)
{
// create time steps with their "name", demand, setup cost,
// production cost per unit, inventory cost per unit
var csv = new CsvReader(File.OpenText("timesteps.csv"));
csv.Configuration.Delimiter = ";";
csv.Configuration.CultureInfo = new CultureInfo("en-US");
var periodInformation = csv.GetRecords<PeriodInformation>();
// Use long names for easier debugging/model understanding.
var config = new Configuration
{
NameHandling = NameHandlingStyle.Manual,
ComputeRemovedVariables = true
};
using (var scope = new ModelScope(config))
{
// create a model, based on given data and the model scope
var clspModel = new CapacitatedLotsizingModel(periodInformation);
var solverCfg = new GurobiSolverConfiguration() { ModelOutputFile = new FileInfo("clsp.lp"), };
// Get a solver instance, change your solver
using (var solver = new GurobiSolver(solverCfg))
{
// solve the model
var solution = solver.Solve(clspModel.Model);
// print objective and variable decisions
Console.WriteLine($"{solution.ObjectiveValues.Single()}");
clspModel.y.Variables.ForEach(x => Console.WriteLine($"{x.ToString().PadRight(36)}: {x.Value}"));
clspModel.x.Variables.ForEach(y => Console.WriteLine($"{y.ToString().PadRight(36)}: {y.Value}"));
clspModel.s.Variables.ForEach(s => Console.WriteLine($"{s.ToString().PadRight(36)}: {s.Value}"));
clspModel.Model.VariableStatistics.WriteCSV(AppDomain.CurrentDomain.BaseDirectory);
PlottingUtils.CreateAndExportLotSizingPlot(clspModel);
Console.ReadLine();
}
}
}
}
}
Next Step
- Creating the Model