public TPModel( IConstraintElementsAbstractFactory constraintElementsAbstractFactory, IConstraintsAbstractFactory constraintsAbstractFactory, ICrossJoinElementsAbstractFactory crossJoinElementsAbstractFactory, ICrossJoinsAbstractFactory crossJoinsAbstractFactory, IDependenciesAbstractFactory dependenciesAbstractFactory, IIndexElementsAbstractFactory indexElementsAbstractFactory, IIndicesAbstractFactory indicesAbstractFactory, IObjectiveFunctionsAbstractFactory objectiveFunctionsAbstractFactory, IParameterElementsAbstractFactory parameterElementsAbstractFactory, IParametersAbstractFactory parametersAbstractFactory, IVariablesAbstractFactory variablesAbstractFactory, ITPInputContext TPInputContext) { this.TPInputContext = TPInputContext; this.Model = dependenciesAbstractFactory.CreateModelFactory().Create(); // Indices // a this.a = indicesAbstractFactory.CreateaFactory().Create( this.TPInputContext.ActiveDays .Select(x => indexElementsAbstractFactory.CreateaIndexElementFactory().Create( x.Key.Value.Value, x.Value)) .ToImmutableList()); // d this.d = indicesAbstractFactory.CreatedFactory().Create( this.TPInputContext.Days .Select(x => indexElementsAbstractFactory.CreatedIndexElementFactory().Create( x.Key.Value.Value, x.Value)) .ToImmutableList()); // k this.k = indicesAbstractFactory.CreatekFactory().Create( this.TPInputContext.BlockTypes .Select(x => indexElementsAbstractFactory.CreatekIndexElementFactory().Create((PositiveInt)x)) .ToImmutableList()); // l this.l = indicesAbstractFactory.CreatelFactory().Create( this.TPInputContext.LengthOfStayDays .Select(x => indexElementsAbstractFactory.CreatelIndexElementFactory().Create((PositiveInt)x)) .ToImmutableList()); // p this.p = indicesAbstractFactory.CreatepFactory().Create( this.TPInputContext.PatientGroups .Select(x => indexElementsAbstractFactory.CreatepIndexElementFactory().Create((PositiveInt)x)) .ToImmutableList()); // r this.r = indicesAbstractFactory.CreaterFactory().Create( this.TPInputContext.OperatingRooms .Entry .Where(x => x.Resource is Location) .Select(x => indexElementsAbstractFactory.CreaterIndexElementFactory().Create((Location)x.Resource)) .ToImmutableList()); // s this.s = indicesAbstractFactory.CreatesFactory().Create( this.TPInputContext.SurgeonGroups .Entry .Where(x => x.Resource is Organization) .Select(x => indexElementsAbstractFactory.CreatesIndexElementFactory().Create((Organization)x.Resource)) .ToImmutableList()); // w this.w = indicesAbstractFactory.CreatewFactory().Create( this.TPInputContext.Wards .Select(x => x.Item1) .Select(x => indexElementsAbstractFactory.CreatewIndexElementFactory().Create(x)) .ToImmutableList()); // Cross joins // ar this.ar = crossJoinsAbstractFactory.CreatearFactory().Create( this.a.Value .SelectMany(b => this.r.Value, (a, b) => crossJoinElementsAbstractFactory.CreatearCrossJoinElementFactory().Create(a, b)) .ToImmutableList()); // pa this.pa = crossJoinsAbstractFactory.CreatepaFactory().Create( this.p.Value .SelectMany(b => this.a.Value, (a, b) => crossJoinElementsAbstractFactory.CreatepaCrossJoinElementFactory().Create(a, b)) .ToImmutableList()); // rk this.rk = crossJoinsAbstractFactory.CreaterkFactory().Create( this.r.Value .SelectMany(b => this.k.Value, (a, b) => crossJoinElementsAbstractFactory.CreaterkCrossJoinElementFactory().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()); // sark this.sark = crossJoinsAbstractFactory.CreatesarkFactory().Create( this.s.Value .SelectMany(b => this.a.Value, (a, b) => crossJoinElementsAbstractFactory.CreatesaCrossJoinElementFactory().Create(a, b)) .SelectMany(b => this.r.Value, (a, b) => crossJoinElementsAbstractFactory.CreatesarCrossJoinElementFactory().Create(a.sIndexElement, a.aIndexElement, b)) .SelectMany(b => this.k.Value, (a, b) => crossJoinElementsAbstractFactory.CreatesarkCrossJoinElementFactory().Create(a.sIndexElement, a.aIndexElement, a.rIndexElement, b)) .ToImmutableList()); // sk this.sk = crossJoinsAbstractFactory.CreateskFactory().Create( this.s.Value .SelectMany(b => this.k.Value, (a, b) => crossJoinElementsAbstractFactory.CreateskCrossJoinElementFactory().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 // BEDS this.BEDS = parametersAbstractFactory.CreateBEDSFactory().Create( (PositiveInt)this.TPInputContext.NumberBeds); // dur(p) this.dur = parametersAbstractFactory.CreatedurFactory().Create( this.TPInputContext.PatientGroupSurgeryDurations .Select(x => parameterElementsAbstractFactory.CreatedurParameterElementFactory().Create( this.p.GetElementAt((PositiveInt)x.Key), x.Value)) .ToImmutableList()); // Length(k) this.Length = parametersAbstractFactory.CreateLengthFactory().Create( this.TPInputContext.BlockTypeTimeBlockLengths .Select(x => parameterElementsAbstractFactory.CreateLengthParameterElementFactory().Create( this.k.GetElementAt((PositiveInt)x.Key), x.Value)) .ToImmutableList()); // ORday(a, r) this.ORday = parametersAbstractFactory.CreateORdayFactory().Create( this.TPInputContext.DayOperatingRoomOperatingCapacities .Select(x => parameterElementsAbstractFactory.CreateORdayParameterElementFactory().Create( this.a.GetElementAt(x.Item1), this.r.GetElementAt(x.Item2), x.Item3)) .ToImmutableList()); // P(s) this.Ps = parametersAbstractFactory.CreatePsFactory().Create( this.TPInputContext.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.TPInputContext.WardSubsetPatientGroups .Select(x => parameterElementsAbstractFactory.CreatePwParameterElementFactory().Create( this.w.GetElementAt(x.Key), this.p.GetElementAt((PositiveInt)x.Value))) .ToImmutableList()); // prob(p, l) this.prob = parametersAbstractFactory.CreateprobFactory().Create( this.TPInputContext.PatientGroupDayLengthOfStayProbabilities .Select(x => parameterElementsAbstractFactory.CreateprobParameterElementFactory().Create( this.p.GetElementAt((PositiveInt)x.Item1), this.l.GetElementAt((PositiveInt)x.Item2), x.Item3)) .ToImmutableList()); // THR(p) this.THR = parametersAbstractFactory.CreateTHRFactory().Create( this.TPInputContext.PatientGroupThroughputs .Select(x => parameterElementsAbstractFactory.CreateTHRParameterElementFactory().Create( this.p.GetElementAt((PositiveInt)x.Key), (PositiveInt)x.Value)) .ToImmutableList()); // W this.W = parametersAbstractFactory.CreateWFactory().Create( this.TPInputContext.Wards .Select(x => parameterElementsAbstractFactory.CreateWParameterElementFactory().Create( this.w.GetElementAt(x.Item1), x.Item2.Select(i => this.s.GetElementAt(i)).ToImmutableList())) .ToImmutableList()); // α(w) this.α = parametersAbstractFactory.CreateαFactory().Create( this.TPInputContext.Wardα .Select(x => parameterElementsAbstractFactory.CreateαParameterElementFactory().Create( this.w.GetElementAt(x.Key), (FhirDecimal)x.Value)) .ToImmutableList()); // β(w) this.β = parametersAbstractFactory.CreateβFactory().Create( this.TPInputContext.Wardβ .Select(x => parameterElementsAbstractFactory.CreateβParameterElementFactory().Create( this.w.GetElementAt(x.Key), (FhirDecimal)x.Value)) .ToImmutableList()); // γ(w) this.γ = parametersAbstractFactory.CreateγFactory().Create( this.TPInputContext.Wardγ .Select(x => parameterElementsAbstractFactory.CreateγParameterElementFactory().Create( this.w.GetElementAt(x.Key), (FhirDecimal)x.Value)) .ToImmutableList()); // Variables // x(p, a) this.x = variablesAbstractFactory.CreateTPxFactory().Create( dependenciesAbstractFactory.CreateVariableCollectionFactory().Create( model: this.Model, indexSet1: this.p.Value, indexSet2: this.a.Value, lowerBoundGenerator: (a, b) => 0, upperBoundGenerator: (a, b) => int.MaxValue, variableTypeGenerator: (a, b) => VariableType.Integer)); // y(w) this.y = variablesAbstractFactory.CreateTPyFactory().Create( dependenciesAbstractFactory.CreateVariableCollectionFactory().Create( model: this.Model, indexSet1: this.w.Value, lowerBoundGenerator: (a) => 0, upperBoundGenerator: (a) => int.MaxValue, variableTypeGenerator: (a) => VariableType.Integer)); // z(s, a, r, k) this.z = variablesAbstractFactory.CreateTPzFactory().Create( dependenciesAbstractFactory.CreateVariableCollectionFactory().Create( model: this.Model, indexSet1: this.s.Value, indexSet2: this.a.Value, indexSet3: this.r.Value, indexSet4: this.k.Value, lowerBoundGenerator: (a, b, c, d) => 0, upperBoundGenerator: (a, b, c, d) => 1, variableTypeGenerator: (a, b, c, d) => VariableType.Binary)); // δMinus(w, d) this.δMinus = variablesAbstractFactory.CreateδMinusFactory().Create( dependenciesAbstractFactory.CreateVariableCollectionFactory().Create( model: this.Model, indexSet1: this.w.Value, indexSet2: this.d.Value, lowerBoundGenerator: (a, b) => 0, upperBoundGenerator: (a, b) => double.MaxValue, variableTypeGenerator: (a, b) => VariableType.Continuous)); // δPlus(w) this.δPlus_w = variablesAbstractFactory.CreateδPluswFactory().Create( dependenciesAbstractFactory.CreateVariableCollectionFactory().Create( model: this.Model, indexSet1: this.w.Value, lowerBoundGenerator: (a) => 0, upperBoundGenerator: (a) => double.MaxValue, variableTypeGenerator: (a) => VariableType.Continuous)); // δPlus(w, d) this.δPlus_wd = variablesAbstractFactory.CreateδPluswdFactory().Create( dependenciesAbstractFactory.CreateVariableCollectionFactory().Create( model: this.Model, indexSet1: this.w.Value, indexSet2: this.d.Value, lowerBoundGenerator: (a, b) => 0, upperBoundGenerator: (a, b) => double.MaxValue, variableTypeGenerator: (a, b) => VariableType.Continuous)); // μ(w, d) this.μ = variablesAbstractFactory.CreateμFactory().Create( dependenciesAbstractFactory.CreateVariableCollectionFactory().Create( model: this.Model, indexSet1: this.w.Value, indexSet2: this.d.Value, lowerBoundGenerator: (a, b) => 0, upperBoundGenerator: (a, b) => double.MaxValue, variableTypeGenerator: (a, b) => VariableType.Continuous)); // Variance(w) this.Variance_w = variablesAbstractFactory.CreateVariancewFactory().Create( dependenciesAbstractFactory.CreateVariableCollectionFactory().Create( model: this.Model, indexSet1: this.w.Value, lowerBoundGenerator: (a) => 0, upperBoundGenerator: (a) => double.MaxValue, variableTypeGenerator: (a) => VariableType.Continuous)); // Variance(w, d) this.Variance_wd = variablesAbstractFactory.CreateVariancewdFactory().Create( dependenciesAbstractFactory.CreateVariableCollectionFactory().Create( model: this.Model, indexSet1: this.w.Value, indexSet2: this.d.Value, lowerBoundGenerator: (a, b) => 0, upperBoundGenerator: (a, b) => double.MaxValue, variableTypeGenerator: (a, b) => VariableType.Continuous)); // Constraints // Constraint (2′′) this.Model.AddConstraint( constraintsAbstractFactory.CreateTPConstraint2Factory().Create( this.w, this.BEDS, this.y) .Value); // Constraints (9′) this.Model.AddConstraints( this.p.Value .Select( i => constraintElementsAbstractFactory.CreateConstraints9ConstraintElementFactory().Create( i, this.a, this.THR, this.x) .Value)); // Constraints (11) this.Model.AddConstraints( this.wd.Value .Select( i => constraintElementsAbstractFactory.CreateConstraints11ConstraintElementFactory().Create( i.dIndexElement, i.wIndexElement, this.d, this.l, this.pa, this.Pw, this.prob, this.x, this.μ) .Value)); // Constraints (12) this.Model.AddConstraints( this.wd.Value .Select( i => constraintElementsAbstractFactory.CreateConstraints12ConstraintElementFactory().Create( i.dIndexElement, i.wIndexElement, this.d, this.l, this.pa, this.Pw, this.prob, this.x, this.Variance_wd) .Value)); // Constraints (13L) this.Model.AddConstraints( this.wd.Value .Select( i => constraintElementsAbstractFactory.CreateConstraints13LConstraintElementFactory().Create( i.dIndexElement, i.wIndexElement, this.y, this.δMinus, this.μ) .Value)); // Constraints (13M) this.Model.AddConstraints( this.wd.Value .Select( i => constraintElementsAbstractFactory.CreateConstraints13MConstraintElementFactory().Create( i.dIndexElement, i.wIndexElement, this.y, this.δPlus_wd, this.μ) .Value)); // Constraints (13U) this.Model.AddConstraints( this.wd.Value .Select( i => constraintElementsAbstractFactory.CreateConstraints13UConstraintElementFactory().Create( i.dIndexElement, i.wIndexElement, this.δPlus_w, this.δPlus_wd) .Value)); // Constraints (14) this.Model.AddConstraints( this.wd.Value .Select( i => constraintElementsAbstractFactory.CreateConstraints14ConstraintElementFactory().Create( i.dIndexElement, i.wIndexElement, this.Variance_w, this.Variance_wd) .Value)); // Constraints (15) this.Model.AddConstraints( this.ar.Value .Select( i => constraintElementsAbstractFactory.CreateConstraints15ConstraintElementFactory().Create( i.aIndexElement, i.rIndexElement, this.sk, this.Length, this.ORday, this.z) .Value)); // Constraints (16) this.Model.AddConstraints( this.sa.Value .Select( i => constraintElementsAbstractFactory.CreateConstraints16ConstraintElementFactory().Create( i.aIndexElement, i.sIndexElement, this.p, this.rk, this.dur, this.Length, this.Ps, this.x, this.z) .Value)); // Objective Function (10) this.Model.AddObjective( objectiveFunctionsAbstractFactory.CreateTPObjectiveFunctionFactory().Create( dependenciesAbstractFactory.CreateObjectiveFactory(), this.d, this.w, this.α, this.β, this.γ, this.δMinus, this.δPlus_w, this.Variance_w) .Value); }