11 public bool CanBuild(LotSizingInstance instance)
13 if(instance is
null||instance.PlanningHorizon<=0)
return false;
19 out ProductionSchedulingProfile? profile) ||
21 profile is
null)
return false;
23 if(profile.BucketMode!=SchedulingBucketMode.MacroMicro ||
24 !profile.HasExplicitMicroPeriodGrid ||
25 profile.MicroPeriodLengthMode!=MicroPeriodLengthMode.Variable ||
26 profile.MicroPeriodAssignmentMode!=MicroPeriodAssignmentMode.SingleItem ||
27 profile.MicroPeriodCount is
null ||
28 profile.MicroPeriodCount.PlanningHorizon!=instance.PlanningHorizon)
return false;
30 for(
int period=1;period<=instance.PlanningHorizon;period++)
32 if(profile.MicroPeriodCount.GetCount(period)<=0)
return false;
35 if(profile.MaximumSetupCount is not
null &&
36 profile.MaximumSetupCount.PlanningHorizon!=instance.PlanningHorizon)
return false;
38 if(profile.MaximumProducedItemCount is not
null &&
39 profile.MaximumProducedItemCount.PlanningHorizon!=instance.PlanningHorizon)
return false;
41 var capacityConstraint=wc.CapacityConstraint;
42 if(capacityConstraint is
null ||
43 capacityConstraint.PlanningHorizon!=instance.PlanningHorizon)
return false;
45 if(wc.AdditionalCapacity is not
null &&
46 wc.AdditionalCapacity.PlanningHorizon!=instance.PlanningHorizon)
return false;
48 LotSizingProblemFeatures features;
51 features=LotSizingProblemFeatureExtractor.Extract(instance.SupplyChain);
53 catch(InvalidOperationException)
58 if(features.HasMinimumLotSizes ||
59 features.HasMaximumLotSizes ||
60 features.HasLotSizeMultiples ||
61 features.IsMultiSite)
return false;
63 if(instance.SupplyChain.PeriodicOperatingExpenditureBudget is not
null)
return false;
65 if(instance.SupplyChain.ObjectivePolicy is not
null &&
66 (instance.SupplyChain.ObjectivePolicy.AggregationMode!=ObjectiveAggregationMode.Single ||
67 instance.SupplyChain.ObjectivePolicy.PrimaryObjectiveKind!=OptimizationObjectiveKind.Economic))
return false;
70 if(routings.Count<2 ||
71 routings.GroupBy(routing=>routing.ItemId).Any(group=>group.Count()!=1))
return false;
73 var itemIds=routings.Select(routing=>routing.ItemId).ToHashSet();
75 if(profile.HasInitialSetupState &&
76 !itemIds.Contains(profile.InitialSetupItemId))
return false;
78 foreach(ProductionRouting routing
in routings)
80 if(routing.WorkCenters.Count!=1 ||
81 routing.WorkCenters[0].PlantId!=plantId ||
82 routing.WorkCenters[0].WorkCenterId!=wc.Id)
return false;
84 if(routing.GroupingConstraint is not
null &&
85 routing.GroupingConstraint.PlanningHorizon!=instance.PlanningHorizon)
return false;
92 out ProductionCharacteristic? characteristic) ||
93 characteristic is
null)
return false;
95 var unitCapacityConsumption=characteristic.UnitCapacityConsumption;
96 if(unitCapacityConsumption is
null ||
97 unitCapacityConsumption.PlanningHorizon!=instance.PlanningHorizon)
return false;
99 if(characteristic.SetupTime is not
null &&
100 characteristic.SetupTime.PlanningHorizon!=instance.PlanningHorizon)
return false;
102 if(characteristic.FixedSetupCost is not
null &&
103 characteristic.FixedSetupCost.PlanningHorizon!=instance.PlanningHorizon)
return false;
105 if(characteristic.StartUpTime is not
null &&
106 characteristic.StartUpTime.PlanningHorizon!=instance.PlanningHorizon)
return false;
108 if(characteristic.StartUpCost is not
null &&
109 characteristic.StartUpCost.PlanningHorizon!=instance.PlanningHorizon)
return false;
111 for(
int period=1;period<=instance.PlanningHorizon;period++)
113 double cap=capacityConstraint[period];
114 double consumption=unitCapacityConsumption[period];
115 double startUpTime=characteristic.StartUpTime?[period]??0.0;
116 double startUpCost=characteristic.StartUpCost?[period]??0.0;
118 if(!
double.IsFinite(cap) ||
120 !
double.IsFinite(consumption) ||
122 !
double.IsFinite(startUpTime) ||
124 !
double.IsFinite(startUpCost) ||
125 startUpCost<0)
return false;
129 if(profile.Changeovers.Any(
131 changeover.FromItemId==changeover.ToItemId ||
132 !itemIds.Contains(changeover.FromItemId) ||
133 !itemIds.Contains(changeover.ToItemId) ||
134 (changeover.ChangeoverTime is not
null &&
135 changeover.ChangeoverTime.PlanningHorizon!=instance.PlanningHorizon) ||
136 (changeover.ChangeoverCost is not
null &&
137 changeover.ChangeoverCost.PlanningHorizon!=instance.PlanningHorizon)))
return false;
139 if(profile.Changeovers
140 .GroupBy(changeover=>(changeover.FromItemId,changeover.ToItemId))
141 .Any(group=>group.Count()>1))
return false;