예제 #1
0
 public Task <IHM5OutputContext> Solve(
     IAbstractFactory abstractFactory,
     IHM5Configuration HM5Configuration,
     IHM5InputContext HM5InputContext,
     ISolverConfiguration solverConfiguration)
 {
     return(abstractFactory.CreateSolutionsAbstractFactory().CreateHM5SolutionFactory().Create().Solve(
                abstractFactory.CreateCalculationsAbstractFactory(),
                abstractFactory.CreateConstraintElementsAbstractFactory(),
                abstractFactory.CreateConstraintsAbstractFactory(),
                abstractFactory.CreateContextsAbstractFactory(),
                abstractFactory.CreateCrossJoinElementsAbstractFactory(),
                abstractFactory.CreateCrossJoinsAbstractFactory(),
                abstractFactory.CreateDependenciesAbstractFactory(),
                abstractFactory.CreateIndexElementsAbstractFactory(),
                abstractFactory.CreateIndicesAbstractFactory(),
                abstractFactory.CreateModelsAbstractFactory(),
                abstractFactory.CreateObjectiveFunctionsAbstractFactory(),
                abstractFactory.CreateParameterElementsAbstractFactory(),
                abstractFactory.CreateParametersAbstractFactory(),
                abstractFactory.CreateResultElementsAbstractFactory(),
                abstractFactory.CreateResultsAbstractFactory(),
                abstractFactory.CreateVariablesAbstractFactory(),
                HM5Configuration,
                HM5InputContext,
                solverConfiguration));
 }
        public IHM5InputContext Create(
            ImmutableList <INullableValue <int> > weekdays,
            ImmutableList <Tuple <Organization, ImmutableList <Organization> > > surgicalSpecialties,
            ImmutableList <INullableValue <int> > lengthOfStayDays,
            Bundle operatingRooms,
            Bundle surgeons,
            ImmutableList <KeyValuePair <INullableValue <int>, FhirDateTime> > planningHorizon,
            ImmutableList <INullableValue <int> > scenarios,
            Duration timeBlockLength,
            ImmutableList <Tuple <Organization, INullableValue <int>, Duration> > surgeonScenarioWeightedAverageSurgicalDurations,
            ImmutableList <KeyValuePair <Organization, INullableValue <int> > > surgeonLengthOfStayMaximums,
            ImmutableList <Tuple <Organization, INullableValue <int>, INullableValue <int> > > surgeonScenarioMaximumNumberPatients,
            ImmutableList <Tuple <Organization, INullableValue <int>, INullableValue <int>, INullableValue <decimal> > > surgeonDayScenarioLengthOfStayProbabilities,
            INullableValue <int> numberDaysPerWeek,
            ImmutableList <Tuple <Organization, Location, FhirDateTime, INullableValue <bool> > > surgeonOperatingRoomDayAssignments,
            ImmutableList <Tuple <Organization, Location, INullableValue <bool> > > surgeonOperatingRoomAssignments,
            ImmutableList <Tuple <Location, FhirDateTime, INullableValue <bool> > > operatingRoomDayAssignedAvailabilities,
            ImmutableList <Tuple <Organization, INullableValue <int>, INullableValue <decimal> > > surgeonScenarioMaximumNumberPatientMeans,
            ImmutableList <KeyValuePair <INullableValue <int>, INullableValue <decimal> > > scenarioProbabilities,
            ImmutableList <Tuple <Organization, INullableValue <int>, INullableValue <decimal> > > surgeonScenarioMaximumNumberPatientStandardDeviations,
            ImmutableList <Tuple <Organization, INullableValue <int>, INullableValue <int>, INullableValue <decimal> > > surgeonDayScenarioCumulativeNumberPatients,
            INullableValue <int> maximumNumberRecoveryWardBeds)
        {
            IHM5InputContext context = null;

            try
            {
                context = new HM5InputContext(
                    weekdays,
                    surgicalSpecialties,
                    lengthOfStayDays,
                    operatingRooms,
                    surgeons,
                    planningHorizon,
                    scenarios,
                    timeBlockLength,
                    surgeonScenarioWeightedAverageSurgicalDurations,
                    surgeonLengthOfStayMaximums,
                    surgeonScenarioMaximumNumberPatients,
                    surgeonDayScenarioLengthOfStayProbabilities,
                    numberDaysPerWeek,
                    surgeonOperatingRoomDayAssignments,
                    surgeonOperatingRoomAssignments,
                    operatingRoomDayAssignedAvailabilities,
                    surgeonScenarioMaximumNumberPatientMeans,
                    scenarioProbabilities,
                    surgeonScenarioMaximumNumberPatientStandardDeviations,
                    surgeonDayScenarioCumulativeNumberPatients,
                    maximumNumberRecoveryWardBeds);
            }
            catch (Exception exception)
            {
                this.Log.Error("Exception message: " + exception.Message + " and stacktrace " + exception.StackTrace);
            }

            return(context);
        }
예제 #3
0
        public IHM5Model Create(
            ICalculationsAbstractFactory calculationsAbstractFactory,
            IConstraintElementsAbstractFactory constraintElementsAbstractFactory,
            IConstraintsAbstractFactory constraintsAbstractFactory,
            ICrossJoinElementsAbstractFactory crossJoinElementsAbstractFactory,
            ICrossJoinsAbstractFactory crossJoinsAbstractFactory,
            IDependenciesAbstractFactory dependenciesAbstractFactory,
            IIndexElementsAbstractFactory indexElementsAbstractFactory,
            IIndicesAbstractFactory indicesAbstractFactory,
            IObjectiveFunctionsAbstractFactory objectiveFunctionsAbstractFactory,
            IParameterElementsAbstractFactory parameterElementsAbstractFactory,
            IParametersAbstractFactory parametersAbstractFactory,
            IVariablesAbstractFactory variablesAbstractFactory,
            IHM5InputContext HM5InputContext)
        {
            IHM5Model model = null;

            try
            {
                model = new HM5Model(
                    calculationsAbstractFactory,
                    constraintElementsAbstractFactory,
                    constraintsAbstractFactory,
                    crossJoinElementsAbstractFactory,
                    crossJoinsAbstractFactory,
                    dependenciesAbstractFactory,
                    indexElementsAbstractFactory,
                    indicesAbstractFactory,
                    objectiveFunctionsAbstractFactory,
                    parameterElementsAbstractFactory,
                    parametersAbstractFactory,
                    variablesAbstractFactory,
                    HM5InputContext);
            }
            catch (Exception exception)
            {
                this.Log.Error("Exception message: " + exception.Message + " and stacktrace " + exception.StackTrace);
            }

            return(model);
        }
예제 #4
0
        public Task <IHM5OutputContext> Solve(
            ICalculationsAbstractFactory calculationsAbstractFactory,
            IConstraintElementsAbstractFactory constraintElementsAbstractFactory,
            IConstraintsAbstractFactory constraintsAbstractFactory,
            IContextsAbstractFactory contextsAbstractFactory,
            ICrossJoinElementsAbstractFactory crossJoinElementsAbstractFactory,
            ICrossJoinsAbstractFactory crossJoinsAbstractFactory,
            IDependenciesAbstractFactory dependenciesAbstractFactory,
            IIndexElementsAbstractFactory indexElementsAbstractFactory,
            IIndicesAbstractFactory indicesAbstractFactory,
            IModelsAbstractFactory modelsAbstractFactory,
            IObjectiveFunctionsAbstractFactory objectiveFunctionsAbstractFactory,
            IParameterElementsAbstractFactory parameterElementsAbstractFactory,
            IParametersAbstractFactory parametersAbstractFactory,
            IResultElementsAbstractFactory resultElementsAbstractFactory,
            IResultsAbstractFactory resultsAbstractFactory,
            IVariablesAbstractFactory variablesAbstractFactory,
            IHM5Configuration HM5Configuration,
            IHM5InputContext HM5InputContext,
            ISolverConfiguration solverConfiguration)
        {
            IHM5OutputContext HM5OutputContext = null;

            return(Task.Run(() =>
            {
                using (ModelScope modelScope = dependenciesAbstractFactory.CreateModelScopeFactory().Create(HM5Configuration.Value))
                {
                    IHM5Model model = modelsAbstractFactory.CreateHM5ModelFactory().Create(
                        calculationsAbstractFactory,
                        constraintElementsAbstractFactory,
                        constraintsAbstractFactory,
                        crossJoinElementsAbstractFactory,
                        crossJoinsAbstractFactory,
                        dependenciesAbstractFactory,
                        indexElementsAbstractFactory,
                        indicesAbstractFactory,
                        objectiveFunctionsAbstractFactory,
                        parameterElementsAbstractFactory,
                        parametersAbstractFactory,
                        variablesAbstractFactory,
                        HM5InputContext);

                    using (ISolver solver = dependenciesAbstractFactory.CreateSolverFactory().Create(solverConfiguration))
                    {
                        Solution solution = solver?.Solve(model?.Model);

                        if (solution?.ModelStatus == OPTANO.Modeling.Optimization.Solver.ModelStatus.Feasible)
                        {
                            model.Model.VariableCollections.ForEach(vc => vc.SetVariableValues(solution.VariableValues));

                            HM5OutputContext = contextsAbstractFactory.CreateHM5OutputContextFactory().Create(
                                calculationsAbstractFactory,
                                dependenciesAbstractFactory,
                                resultElementsAbstractFactory,
                                resultsAbstractFactory,
                                model,
                                solution);
                        }
                    }
                }

                return HM5OutputContext;
            }));
        }
예제 #5
0
        public HM5Model(
            ICalculationsAbstractFactory calculationsAbstractFactory,
            IConstraintElementsAbstractFactory constraintElementsAbstractFactory,
            IConstraintsAbstractFactory constraintsAbstractFactory,
            ICrossJoinElementsAbstractFactory crossJoinElementsAbstractFactory,
            ICrossJoinsAbstractFactory crossJoinsAbstractFactory,
            IDependenciesAbstractFactory dependenciesAbstractFactory,
            IIndexElementsAbstractFactory indexElementsAbstractFactory,
            IIndicesAbstractFactory indicesAbstractFactory,
            IObjectiveFunctionsAbstractFactory objectiveFunctionsAbstractFactory,
            IParameterElementsAbstractFactory parameterElementsAbstractFactory,
            IParametersAbstractFactory parametersAbstractFactory,
            IVariablesAbstractFactory variablesAbstractFactory,
            IHM5InputContext HM5InputContext)
        {
            this.Context = HM5InputContext;

            this.Model = dependenciesAbstractFactory.CreateModelFactory().Create();

            // Indices

            // d1
            this.d1 = indicesAbstractFactory.Created1Factory().Create(
                this.Context.Weekdays
                .Select(x => indexElementsAbstractFactory.Created1IndexElementFactory().Create((PositiveInt)x))
                .ToImmutableList());

            // d2
            this.d2 = indicesAbstractFactory.Created2Factory().Create(
                this.Context.Weekdays
                .Select(x => indexElementsAbstractFactory.Created2IndexElementFactory().Create((PositiveInt)x))
                .ToImmutableList());

            // j
            this.j = indicesAbstractFactory.CreatejFactory().Create(
                this.Context.SurgicalSpecialties
                .Select(x => x.Item1)
                .Select(x => indexElementsAbstractFactory.CreatejIndexElementFactory().Create(x))
                .ToImmutableList());

            // l
            this.l = indicesAbstractFactory.CreatelFactory().Create(
                this.Context.LengthOfStayDays
                .Select(x => indexElementsAbstractFactory.CreatelIndexElementFactory().Create((PositiveInt)x))
                .ToImmutableList());

            // r
            this.r = indicesAbstractFactory.CreaterFactory().Create(
                this.Context.OperatingRooms
                .Entry
                .Where(x => x.Resource is Location)
                .Select(x => indexElementsAbstractFactory.CreaterIndexElementFactory().Create((Location)x.Resource))
                .ToImmutableList());

            // s
            this.s = indicesAbstractFactory.CreatesFactory().Create(
                this.Context.Surgeons
                .Entry
                .Where(x => x.Resource is Organization)
                .Select(x => indexElementsAbstractFactory.CreatesIndexElementFactory().Create((Organization)x.Resource))
                .ToImmutableList());

            // t
            this.t = indicesAbstractFactory.CreatetFactory().Create(
                this.Context.PlanningHorizon
                .Select(x => indexElementsAbstractFactory.CreatetIndexElementFactory().Create(
                            x.Key.Value.Value,
                            x.Value))
                .ToImmutableList());

            // Λ
            this.Λ = indicesAbstractFactory.CreateΛFactory().Create(
                this.Context.Scenarios
                .Select(x => indexElementsAbstractFactory.CreateΛIndexElementFactory().Create((PositiveInt)x))
                .ToImmutableList());

            // Cross joins

            // rd1
            this.rd1 = crossJoinsAbstractFactory.Createrd1Factory().Create(
                this.r.Value
                .SelectMany(b => this.d1.Value, (a, b) => crossJoinElementsAbstractFactory.Createrd1CrossJoinElementFactory().Create(a, b))
                .ToImmutableList());

            // rd1d2
            this.rd1d2 = crossJoinsAbstractFactory.Createrd1d2Factory().Create(
                this.r.Value
                .SelectMany(b => this.d1.Value, (a, b) => crossJoinElementsAbstractFactory.Createrd1CrossJoinElementFactory().Create(a, b))
                .SelectMany(b => this.d2.Value, (a, b) => crossJoinElementsAbstractFactory.Createrd1d2CrossJoinElementFactory().Create(a.rIndexElement, a.d1IndexElement, b))
                .ToImmutableList());

            // rd2
            this.rd2 = crossJoinsAbstractFactory.Createrd2Factory().Create(
                this.r.Value
                .SelectMany(b => this.d2.Value, (a, b) => crossJoinElementsAbstractFactory.Createrd2CrossJoinElementFactory().Create(a, b))
                .ToImmutableList());

            // rt
            this.rt = crossJoinsAbstractFactory.CreatertFactory().Create(
                this.r.Value
                .SelectMany(b => this.t.Value, (a, b) => crossJoinElementsAbstractFactory.CreatertCrossJoinElementFactory().Create(a, b))
                .ToImmutableList());

            // slΛ
            this.slΛ = crossJoinsAbstractFactory.CreateslΛFactory().Create(
                this.s.Value
                .SelectMany(b => this.l.Value, (a, b) => crossJoinElementsAbstractFactory.CreateslCrossJoinElementFactory().Create(a, b))
                .SelectMany(b => this.Λ.Value, (a, b) => crossJoinElementsAbstractFactory.CreateslΛCrossJoinElementFactory().Create(a.sIndexElement, a.lIndexElement, b))
                .ToImmutableList());

            // srd2
            this.srd2 = crossJoinsAbstractFactory.Createsrd2Factory().Create(
                this.s.Value
                .SelectMany(b => this.r.Value, (a, b) => crossJoinElementsAbstractFactory.CreatesrCrossJoinElementFactory().Create(a, b))
                .SelectMany(b => this.d2.Value, (a, b) => crossJoinElementsAbstractFactory.Createsrd2CrossJoinElementFactory().Create(a.sIndexElement, a.rIndexElement, b))
                .ToImmutableList());

            // srd2t
            this.srd2t = crossJoinsAbstractFactory.Createsrd2tFactory().Create(
                this.s.Value
                .SelectMany(b => this.r.Value, (a, b) => crossJoinElementsAbstractFactory.CreatesrCrossJoinElementFactory().Create(a, b))
                .SelectMany(b => this.d2.Value, (a, b) => crossJoinElementsAbstractFactory.Createsrd2CrossJoinElementFactory().Create(a.sIndexElement, a.rIndexElement, b))
                .SelectMany(b => this.t.Value, (a, b) => crossJoinElementsAbstractFactory.Createsrd2tCrossJoinElementFactory().Create(a.sIndexElement, a.rIndexElement, a.d2IndexElement, b))
                .ToImmutableList());

            // srt
            this.srt = crossJoinsAbstractFactory.CreatesrtFactory().Create(
                this.s.Value
                .SelectMany(b => this.r.Value, (a, b) => crossJoinElementsAbstractFactory.CreatesrCrossJoinElementFactory().Create(a, b))
                .SelectMany(b => this.t.Value, (a, b) => crossJoinElementsAbstractFactory.CreatesrtCrossJoinElementFactory().Create(a.sIndexElement, a.rIndexElement, b))
                .ToImmutableList());

            // st
            this.st = crossJoinsAbstractFactory.CreatestFactory().Create(
                this.s.Value
                .SelectMany(b => this.t.Value, (a, b) => crossJoinElementsAbstractFactory.CreatestCrossJoinElementFactory().Create(a, b))
                .ToImmutableList());

            // sΛ
            this.sΛ = crossJoinsAbstractFactory.CreatesΛFactory().Create(
                this.s.Value
                .SelectMany(b => this.Λ.Value, (a, b) => crossJoinElementsAbstractFactory.CreatesΛCrossJoinElementFactory().Create(a, b))
                .ToImmutableList());

            // tΛ
            this.tΛ = crossJoinsAbstractFactory.CreatetΛFactory().Create(
                this.t.Value
                .SelectMany(b => this.Λ.Value, (a, b) => crossJoinElementsAbstractFactory.CreatetΛCrossJoinElementFactory().Create(a, b))
                .ToImmutableList());

            // Parameters

            // H
            this.H = parametersAbstractFactory.CreateHFactory().Create(
                this.Context.TimeBlockLength);

            // h(s, Λ)
            this.h = parametersAbstractFactory.CreatehFactory().Create(
                this.Context.SurgeonScenarioWeightedAverageSurgicalDurations
                .Select(x => parameterElementsAbstractFactory.CreatehParameterElementFactory().Create(
                            this.s.GetElementAt(x.Item1),
                            this.Λ.GetElementAt((PositiveInt)x.Item2),
                            x.Item3))
                .ToImmutableList());

            // L(s)
            this.L = parametersAbstractFactory.CreateLFactory().Create(
                this.Context.SurgeonLengthOfStayMaximums
                .Select(x => parameterElementsAbstractFactory.CreateLParameterElementFactory().Create(
                            this.s.GetElementAt(x.Key),
                            (PositiveInt)x.Value))
                .ToImmutableList());

            // n(s, Λ)
            this.n = parametersAbstractFactory.CreatenFactory().Create(
                this.Context.SurgeonScenarioMaximumNumberPatients
                .Select(x => parameterElementsAbstractFactory.CreatenParameterElementFactory().Create(
                            this.s.GetElementAt(x.Item1),
                            this.Λ.GetElementAt((PositiveInt)x.Item2),
                            (PositiveInt)x.Item3))
                .ToImmutableList());

            // p(s, l, Λ)
            this.p = parametersAbstractFactory.CreatepFactory().Create(
                this.Context.SurgeonDayScenarioLengthOfStayProbabilities
                .Select(x => parameterElementsAbstractFactory.CreatepParameterElementFactory().Create(
                            this.s.GetElementAt(x.Item1),
                            this.l.GetElementAt((PositiveInt)x.Item2),
                            this.Λ.GetElementAt((PositiveInt)x.Item3),
                            (FhirDecimal)x.Item4))
                .ToImmutableList());

            // Δ(j)
            // Must be populated before S1
            this.Δ = parametersAbstractFactory.CreateΔFactory().Create(
                this.Context.SurgicalSpecialties
                .Select(x => parameterElementsAbstractFactory.CreateΔParameterElementFactory().Create(
                            this.j.GetElementAt(x.Item1),
                            x.Item2.Select(i => this.s.GetElementAt(i)).ToImmutableList()))
                .ToImmutableList());

            // x(s, r, t)
            // Must be populated before S1
            this.x = parametersAbstractFactory.CreatexFactory().Create(
                this.Context.SurgeonOperatingRoomDayAssignments
                .Select(x => parameterElementsAbstractFactory.CreatexParameterElementFactory().Create(
                            this.s.GetElementAt(x.Item1),
                            this.r.GetElementAt(x.Item2),
                            this.t.GetElementAt(x.Item3),
                            (FhirBoolean)x.Item4))
                .ToImmutableList());

            // S1
            this.S1 = calculationsAbstractFactory.CreateS1CalculationFactory().Create().Calculate(
                parameterElementsAbstractFactory.CreateS1ParameterElementFactory(),
                parametersAbstractFactory.CreateS1Factory(),
                this.r,
                this.x,
                this.Δ);

            // W
            // Must be populated before S2
            this.W = parametersAbstractFactory.CreateWFactory().Create(
                (PositiveInt)this.Context.NumberDaysPerWeek);

            // S2
            this.S2 = calculationsAbstractFactory.CreateS2CalculationFactory().Create().Calculate(
                parameterElementsAbstractFactory.CreateS2ParameterElementFactory(),
                parametersAbstractFactory.CreateS2Factory(),
                this.d1,
                this.d2,
                this.r,
                this.t,
                this.rd1d2,
                this.W,
                this.x,
                this.Δ);

            // y(s, r)
            this.y = parametersAbstractFactory.CreateyFactory().Create(
                this.Context.SurgeonOperatingRoomAssignments
                .Select(x => parameterElementsAbstractFactory.CreateyParameterElementFactory().Create(
                            this.s.GetElementAt(x.Item1),
                            this.r.GetElementAt(x.Item2),
                            (FhirBoolean)x.Item3))
                .ToImmutableList());

            // γ(r, t)
            this.γ = parametersAbstractFactory.CreateγFactory().Create(
                this.Context.OperatingRoomDayAssignedAvailabilities
                .Select(x => parameterElementsAbstractFactory.CreateγParameterElementFactory().Create(
                            this.r.GetElementAt(x.Item1),
                            this.t.GetElementAt(x.Item2),
                            (FhirBoolean)x.Item3))
                .ToImmutableList());

            // μ(s, Λ)
            this.μ = parametersAbstractFactory.CreateμFactory().Create(
                this.Context.SurgeonScenarioMaximumNumberPatientMeans
                .Select(x => parameterElementsAbstractFactory.CreateμParameterElementFactory().Create(
                            this.s.GetElementAt(x.Item1),
                            this.Λ.GetElementAt((PositiveInt)x.Item2),
                            (FhirDecimal)x.Item3))
                .ToImmutableList());

            // Ρ(Λ)
            this.Ρ = parametersAbstractFactory.CreateΡFactory().Create(
                this.Context.ScenarioProbabilities
                .Select(x => parameterElementsAbstractFactory.CreateΡParameterElementFactory().Create(
                            this.Λ.GetElementAt((PositiveInt)x.Key),
                            (FhirDecimal)x.Value))
                .ToImmutableList());

            // σ(s, Λ)
            this.σ = parametersAbstractFactory.CreateσFactory().Create(
                this.Context.SurgeonScenarioMaximumNumberPatientStandardDeviations
                .Select(x => parameterElementsAbstractFactory.CreateσParameterElementFactory().Create(
                            this.s.GetElementAt(x.Item1),
                            this.Λ.GetElementAt((PositiveInt)x.Item2),
                            (FhirDecimal)x.Item3))
                .ToImmutableList());

            // ΦHat(s, l, Λ)
            this.ΦHat = parametersAbstractFactory.CreateΦHatFactory().Create(
                this.Context.SurgeonDayScenarioCumulativeNumberPatients
                .Select(x => parameterElementsAbstractFactory.CreateΦHatParameterElementFactory().Create(
                            this.s.GetElementAt(x.Item1),
                            this.l.GetElementAt((PositiveInt)x.Item2),
                            this.Λ.GetElementAt((PositiveInt)x.Item3),
                            (FhirDecimal)x.Item4))
                .ToImmutableList());

            // Ω
            this.Ω = parametersAbstractFactory.CreateΩFactory().Create(
                (PositiveInt)this.Context.MaximumNumberRecoveryWardBeds);

            // Variables

            // IHat(t, Λ)
            this.IHat = variablesAbstractFactory.CreateIHatFactory().Create(
                dependenciesAbstractFactory.CreateVariableCollectionFactory().Create(
                    model: this.Model,
                    indexSet1: this.t.Value,
                    indexSet2: this.Λ.Value,
                    lowerBoundGenerator: (a, b) => 0,
                    upperBoundGenerator: (a, b) => double.MaxValue,
                    variableTypeGenerator: (a, b) => VariableType.Continuous));

            // xHat(s, r, t)
            this.xHat = variablesAbstractFactory.CreatexHatFactory().Create(
                dependenciesAbstractFactory.CreateVariableCollectionFactory().Create(
                    model: this.Model,
                    indexSet1: this.s.Value,
                    indexSet2: this.r.Value,
                    indexSet3: this.t.Value,
                    lowerBoundGenerator: (a, b, c) => 0,
                    upperBoundGenerator: (a, b, c) => 1,
                    variableTypeGenerator: (a, b, c) => VariableType.Binary));

            // z(s, t)
            this.z = variablesAbstractFactory.CreatezFactory().Create(
                dependenciesAbstractFactory.CreateVariableCollectionFactory().Create(
                    model: this.Model,
                    indexSet1: this.s.Value,
                    indexSet2: this.t.Value,
                    lowerBoundGenerator: (a, b) => 0,
                    upperBoundGenerator: (a, b) => 1,
                    variableTypeGenerator: (a, b) => VariableType.Binary));

            // α(r, d1, d2)
            this.α = variablesAbstractFactory.CreateαFactory().Create(
                dependenciesAbstractFactory.CreateVariableCollectionFactory().Create(
                    model: this.Model,
                    indexSet1: this.r.Value,
                    indexSet2: this.d1.Value,
                    indexSet3: this.d2.Value,
                    lowerBoundGenerator: (a, b, c) => 0,
                    upperBoundGenerator: (a, b, c) => 1,
                    variableTypeGenerator: (a, b, c) => VariableType.Binary));

            // Constraints

            // Constraints 1
            this.Model.AddConstraints(
                this.st.Value
                .Select(
                    x => constraintElementsAbstractFactory.CreateConstraints1ConstraintElementFactory().Create(
                        x.sIndexElement,
                        x.tIndexElement,
                        this.r,
                        this.xHat,
                        this.z)
                    .Value));

            // Constraints 2
            this.Model.AddConstraints(
                this.rt.Value
                .Select(
                    x => constraintElementsAbstractFactory.CreateConstraints2ConstraintElementFactory().Create(
                        x.rIndexElement,
                        x.tIndexElement,
                        this.s,
                        this.γ,
                        this.xHat)
                    .Value));

            // Constraints 3
            this.Model.AddConstraints(
                this.srt.Value
                .Select(
                    x => constraintElementsAbstractFactory.CreateConstraints3ConstraintElementFactory().Create(
                        x.rIndexElement,
                        x.sIndexElement,
                        x.tIndexElement,
                        this.y,
                        this.xHat)
                    .Value));

            // Constraints 4
            this.Model.AddConstraints(
                this.tΛ.Value
                .Select(
                    x => constraintElementsAbstractFactory.CreateConstraints4ConstraintElementFactory().Create(
                        x.tIndexElement,
                        x.ΛIndexElement,
                        this.l,
                        this.t,
                        this.st,
                        this.ΦHat,
                        this.IHat,
                        this.z)
                    .Value));

            // Constraints 5
            this.Model.AddConstraints(
                this.rd1.Value
                .Where(x => this.S1.IsThereElementAt(x.rIndexElement))
                .Select(
                    x => constraintElementsAbstractFactory.CreateConstraints5ConstraintElementFactory().Create(
                        x.d1IndexElement,
                        x.rIndexElement,
                        this.d2,
                        this.α)
                    .Value));

            // Constraints 6
            this.Model.AddConstraints(
                this.rd2.Value
                .Where(x => this.S1.IsThereElementAt(x.rIndexElement))
                .Select(
                    x => constraintElementsAbstractFactory.CreateConstraints6ConstraintElementFactory().Create(
                        x.d2IndexElement,
                        x.rIndexElement,
                        this.d1,
                        this.α)
                    .Value));

            // Constraints 7
            this.Model.AddConstraints(
                this.rd1d2.Value
                .Where(x => this.S1.IsThereElementAt(x.rIndexElement))
                .Where(x => this.S2.IsThereElementAt(
                           x.rIndexElement,
                           x.d1IndexElement,
                           x.d2IndexElement))
                .Select(
                    x => constraintElementsAbstractFactory.CreateConstraints7ConstraintElementFactory().Create(
                        x.rIndexElement,
                        x.d1IndexElement,
                        x.d2IndexElement,
                        this.α)
                    .Value));

            // Constraints 8
            this.Model.AddConstraints(
                this.srd2.Value
                .Where(x => this.S1.IsThereElementAt(x.rIndexElement))
                .SelectMany(b =>
                            this.t.GetNthElementsAt(
                                0,
                                this.W.Value.Value.Value * ((this.t.GetT() / this.W.Value.Value.Value) - 1),
                                this.W.Value.Value.Value),
                            (a, b) => Tuple.Create(a.sIndexElement, a.rIndexElement, a.d2IndexElement, b))
                .Select(
                    x => constraintElementsAbstractFactory.CreateConstraints8ConstraintElementFactory().Create(
                        x.Item3,
                        x.Item2,
                        x.Item1,
                        x.Item4,
                        this.d1,
                        this.t,
                        this.x,
                        this.xHat,
                        this.α)
                    .Value));

            // Constraints 9
            this.Model.AddConstraints(
                this.srt.Value
                .Where(x => !this.S1.IsThereElementAt(x.rIndexElement))
                .Select(
                    x => constraintElementsAbstractFactory.CreateConstraints9ConstraintElementFactory().Create(
                        x.rIndexElement,
                        x.sIndexElement,
                        x.tIndexElement,
                        this.x,
                        this.xHat)
                    .Value));

            // Objective function
            this.Model.AddObjective(
                objectiveFunctionsAbstractFactory.CreateObjectiveFunctionFactory().Create(
                    dependenciesAbstractFactory.CreateObjectiveFactory(),
                    this.t,
                    this.Λ,
                    this.Ρ,
                    this.IHat)
                .Value);
        }