示例#1
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);
        }
示例#2
0
        public SPModel(
            IConstraintElementsAbstractFactory constraintElementsAbstractFactory,
            IConstraintsAbstractFactory constraintsAbstractFactory,
            ICrossJoinElementsAbstractFactory crossJoinElementsAbstractFactory,
            ICrossJoinsAbstractFactory crossJoinsAbstractFactory,
            IDependenciesAbstractFactory dependenciesAbstractFactory,
            IIndexElementsAbstractFactory indexElementsAbstractFactory,
            IIndicesAbstractFactory indicesAbstractFactory,
            IObjectiveFunctionsAbstractFactory objectiveFunctionsAbstractFactory,
            IParameterElementsAbstractFactory parameterElementsAbstractFactory,
            IParametersAbstractFactory parametersAbstractFactory,
            IVariablesAbstractFactory variablesAbstractFactory,
            ISPInputContext SPInputContext)
        {
            this.SPInputContext = SPInputContext;

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

            // Indices

            // a
            this.a = indicesAbstractFactory.CreateaFactory().Create(
                this.SPInputContext.ActiveDays
                .Select(x => indexElementsAbstractFactory.CreateaIndexElementFactory().Create(
                            x.Key.Value.Value,
                            x.Value))
                .ToImmutableList());

            // d
            this.d = indicesAbstractFactory.CreatedFactory().Create(
                this.SPInputContext.Days
                .Select(x => indexElementsAbstractFactory.CreatedIndexElementFactory().Create(
                            x.Key.Value.Value,
                            x.Value))
                .ToImmutableList());

            // p
            this.p = indicesAbstractFactory.CreatepFactory().Create(
                this.SPInputContext.PatientGroups
                .Select(x => indexElementsAbstractFactory.CreatepIndexElementFactory().Create((PositiveInt)x))
                .ToImmutableList());

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

            // w
            this.w = indicesAbstractFactory.CreatewFactory().Create(
                this.SPInputContext.Wards
                .Select(x => x.Item1)
                .Select(x => indexElementsAbstractFactory.CreatewIndexElementFactory().Create(x))
                .ToImmutableList());

            // Cross joins

            // pa
            this.pa = crossJoinsAbstractFactory.CreatepaFactory().Create(
                this.p.Value
                .SelectMany(b => this.a.Value, (a, b) => crossJoinElementsAbstractFactory.CreatepaCrossJoinElementFactory().Create(a, b))
                .ToImmutableList());

            // sa
            this.sa = crossJoinsAbstractFactory.CreatesaFactory().Create(
                this.s.Value
                .SelectMany(b => this.a.Value, (a, b) => crossJoinElementsAbstractFactory.CreatesaCrossJoinElementFactory().Create(a, b))
                .ToImmutableList());

            // wd
            this.wd = crossJoinsAbstractFactory.CreatewdFactory().Create(
                this.w.Value
                .SelectMany(b => this.d.Value, (a, b) => crossJoinElementsAbstractFactory.CreatewdCrossJoinElementFactory().Create(a, b))
                .ToImmutableList());

            // Parameters

            // A(p, d)
            this.A = parametersAbstractFactory.CreateAFactory().Create(
                this.SPInputContext.PatientGroupDaySubsetActiveDays
                .Select(x => parameterElementsAbstractFactory.CreateAParameterElementFactory().Create(
                            this.p.GetElementAt((PositiveInt)x.Item1),
                            this.d.GetElementAt(x.Item2),
                            this.a.GetElementAt(x.Item3)))
                .ToImmutableList());

            // BEDS
            this.BEDS = parametersAbstractFactory.CreateBEDSFactory().Create(
                (PositiveInt)this.SPInputContext.NumberBeds);

            // BLOCKS
            this.BLOCKS = parametersAbstractFactory.CreateBLOCKSFactory().Create(
                (PositiveInt)this.SPInputContext.NumberBlocks);

            // dur(p)
            this.dur = parametersAbstractFactory.CreatedurFactory().Create(
                this.SPInputContext.PatientGroupSurgeryDurations
                .Select(x => parameterElementsAbstractFactory.CreatedurParameterElementFactory().Create(
                            this.p.GetElementAt((PositiveInt)x.Key),
                            x.Value))
                .ToImmutableList());

            // LB(p)
            this.LB = parametersAbstractFactory.CreateLBFactory().Create(
                this.SPInputContext.PatientGroupNumberPatientLowerBounds
                .Select(x => parameterElementsAbstractFactory.CreateLBParameterElementFactory().Create(
                            this.p.GetElementAt((PositiveInt)x.Key),
                            (PositiveInt)x.Value))
                .ToImmutableList());

            // LENGTH
            this.LENGTH = parametersAbstractFactory.CreateLENGTHFactory().Create(
                this.SPInputContext.TimeBlockLength);

            // P(s)
            this.Ps = parametersAbstractFactory.CreatePsFactory().Create(
                this.SPInputContext.SurgeonGroupSubsetPatientGroups
                .Select(x => parameterElementsAbstractFactory.CreatePsParameterElementFactory().Create(
                            this.s.GetElementAt(x.Key),
                            this.p.GetElementAt((PositiveInt)x.Value)))
                .ToImmutableList());

            // P(w)
            this.Pw = parametersAbstractFactory.CreatePwFactory().Create(
                this.SPInputContext.WardSubsetPatientGroups
                .Select(x => parameterElementsAbstractFactory.CreatePwParameterElementFactory().Create(
                            this.w.GetElementAt(x.Key),
                            this.p.GetElementAt((PositiveInt)x.Value)))
                .ToImmutableList());

            // r
            this.r = parametersAbstractFactory.CreaterFactory().Create(
                this.SPInputContext.PatientGroupProfits
                .Select(x => parameterElementsAbstractFactory.CreaterParameterElementFactory().Create(
                            this.p.GetElementAt((PositiveInt)x.Key),
                            x.Value))
                .ToImmutableList());

            // UB(p)
            this.UB = parametersAbstractFactory.CreateUBFactory().Create(
                this.SPInputContext.PatientGroupNumberPatientUpperBounds
                .Select(x => parameterElementsAbstractFactory.CreateUBParameterElementFactory().Create(
                            this.p.GetElementAt((PositiveInt)x.Key),
                            (PositiveInt)x.Value))
                .ToImmutableList());

            // Variables

            // x(p, a)
            this.x = variablesAbstractFactory.CreateSPxFactory().Create(
                dependenciesAbstractFactory.CreateVariableCollectionFactory().Create(
                    model: this.Model,
                    indexSet1: this.p.Value,
                    indexSet2: this.a.Value,
                    lowerBoundGenerator: (a, b) => 0,
                    upperBoundGenerator: null,
                    variableTypeGenerator: (a, b) => VariableType.Integer));

            // y(w)
            this.y = variablesAbstractFactory.CreateSPyFactory().Create(
                dependenciesAbstractFactory.CreateVariableCollectionFactory().Create(
                    model: this.Model,
                    indexSet1: this.w.Value,
                    lowerBoundGenerator: (a) => 0,
                    upperBoundGenerator: null,
                    variableTypeGenerator: (a) => VariableType.Integer));

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

            // Constraints (2)
            this.Model.AddConstraint(
                constraintsAbstractFactory.CreateSPConstraint2Factory().Create(
                    this.w,
                    this.BEDS,
                    this.y)
                .Value);

            // Constraints (3)
            this.Model.AddConstraints(
                this.wd.Value
                .Select(
                    i => constraintElementsAbstractFactory.CreateConstraints3ConstraintElementFactory().Create(
                        i.dIndexElement,
                        i.wIndexElement,
                        this.pa,
                        this.A,
                        this.Pw,
                        this.x,
                        this.y)
                    .Value));

            // Constraints (4)
            this.Model.AddConstraints(
                this.a.Value
                .Select(
                    i => constraintElementsAbstractFactory.CreateConstraints4ConstraintElementFactory().Create(
                        i,
                        this.s,
                        this.BLOCKS,
                        this.z)
                    .Value));

            // Constraints (5)
            this.Model.AddConstraints(
                this.sa.Value
                .Select(
                    i => constraintElementsAbstractFactory.CreateConstraints5ConstraintElementFactory().Create(
                        i.aIndexElement,
                        i.sIndexElement,
                        this.p,
                        this.dur,
                        this.LENGTH,
                        this.Ps,
                        this.x,
                        this.z)
                    .Value));

            // Constraints (6L)
            this.Model.AddConstraints(
                this.p.Value
                .Select(
                    i => constraintElementsAbstractFactory.CreateConstraints6LConstraintElementFactory().Create(
                        i,
                        this.a,
                        this.LB,
                        this.x)
                    .Value));

            // Constraints (6U)
            this.Model.AddConstraints(
                this.p.Value
                .Select(
                    i => constraintElementsAbstractFactory.CreateConstraints6UConstraintElementFactory().Create(
                        i,
                        this.a,
                        this.UB,
                        this.x)
                    .Value));

            // Objective Function (1)
            this.Model.AddObjective(
                objectiveFunctionsAbstractFactory.CreateSPObjectiveFunctionFactory().Create(
                    dependenciesAbstractFactory.CreateObjectiveFactory(),
                    this.pa,
                    this.r,
                    this.x)
                .Value);
        }