Business Objects & Instantiation
Visualization
The image below visualizes the data created below. For this example we have 5 different subsets with different elements.
Element (Business Object)
Each Element holds its name and value. All elements are contained in Sets.
Element.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SetProblems
{
/// <summary>
/// creates an element for the Set Problem(s)
/// </summary>
public class Element : IElement
{
public Element(string name, double value)
{
this.Name = name;
this.Value = value;
}
/// <summary>
/// the value of the element
/// </summary>
public double Value { get; }
public string Name { get; }
public override string ToString() => this.Name;
}
}
Set of Elements (Business Object)
Each Set holds different Elements and has a designated cost. Elements are stored in a way that the Model can ask if the Element is contained in this Set efficiently. There is also information about the Set being the original full Set or not.
Set_E.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SetProblems
{
/// <summary>
/// creates a Set for the Set Problem(s)
/// </summary>
public class Set_E : ISet_E
{
public Set_E(string name, IEnumerable<IElement> elements, double cost, bool isFullSet)
{
this.Name = name;
this.Elements = new HashSet<IElement>(elements);
this.Cost = cost; // if the cost is 0 it is the original full set!
this.IsFullSet = isFullSet;
}
/// <summary>
/// the list of IElements
/// </summary>
public HashSet<IElement> Elements { get; }
/// <summary>
/// the cost of the set
/// </summary>
public double Cost { get; }
/// <summary>
/// indicates whether the Set is the original full Set
/// </summary>
public bool IsFullSet { get; set; }
/// <summary>
/// name of the set
/// </summary>
public string Name { get; }
IEnumerable<IElement> ISet_E.Elements
{
get
{
return this.Elements;
}
}
/// <summary>
/// readable representation of the set
/// </summary>
/// <returns>string</returns>
public override string ToString() {
var setName = this.Name + " with elements: ";
foreach(var element in this.Elements)
{
setName = setName + element.Name + ", " ;
}
return setName;
}
/// <summary>
/// indicates whether the given element is contained in this Set (true) or not (false)
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
public bool ContainsElement(IElement element)
{
return this.Elements.Contains(element);
}
}
}
Program instance
Instantiation of the different Elements & Sets, the Model, as well as the Solver and an empty Solution. Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SetProblems
{
using System.Configuration;
using OPTANO.Modeling.Common;
using OPTANO.Modeling.Optimization;
using OPTANO.Modeling.Optimization.Configuration;
using OPTANO.Modeling.Optimization.Solver.Gurobi810;
/// <summary>
/// Demo program solving Set-problem(s)
/// </summary>
class Program
{
/// <summary>
/// The main method
/// </summary>
/// <param name="args">
/// no arguments required
/// </param>
static void Main(string[] args)
{
// create example elements
IElement one = new Element("one", 1);
IElement two = new Element("two", 2);
IElement three = new Element("three", 3);
IElement four = new Element("four", 4);
IElement five = new Element("five", 5);
// create full set
ISet_E fullSet = new Set_E("full_set",
new List<IElement> { one, two, three, four, five} , 0, true);
// create subsets
ISet_E subset_1 = new Set_E("subset_1",
new List<IElement> { one, three }, 8, false);
ISet_E subset_2 = new Set_E("subset_2",
new List<IElement> { three, five }, 16, false);
ISet_E subset_3 = new Set_E("subset_3",
new List<IElement> { three }, 6, false);
ISet_E subset_4 = new Set_E("subset_4",
new List<IElement> { one, two, four }, 15, false);
ISet_E subset_5 = new Set_E("subset_5",
new List<IElement> { one, five }, 7, false);
var sets = new List<ISet_E>{subset_1, subset_2, subset_3, subset_4, subset_5};
// 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 setProblemModel = new SetProblemModel(sets, fullSet);
// Get a solver instance, change your solver
using (var solver = new GurobiSolver())
{
// solve the model
var solution = solver.Solve(setProblemModel.Model);
// import the results back into the model
setProblemModel.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues));
// print objective and variable decisions
Console.WriteLine($"{solution.ObjectiveValues.Single()}");
setProblemModel.y.Variables.ForEach(y => Console.WriteLine($"{y.ToString().PadRight(36)}: {y.Value}"));
setProblemModel.Model.VariableStatistics.WriteCSV(AppDomain.CurrentDomain.BaseDirectory);
Console.ReadLine();
}
}
}
}
}
Next Step
- Creating the Model