LotSizingDataModel.Solver 2.0.1
Solver-independent modeling, execution, monitoring and adapter infrastructure.
Loading...
Searching...
No Matches
TransportResourceActivationLinkConstraintFamilyBuilder.cs
Go to the documentation of this file.
1using System;
2using System.Linq;
3using System.Threading;
4using System.Threading.Tasks;
5using LotSizingDataModel.Core.PhysicalModel;
6using LotSizingDataModel.Core.Relationships;
7using LotSizingDataModel.Instance;
11
13
14/// <summary>Links each departure to the shared resource activation and existing per-lane item setup.</summary>
16{
17 public override string ConstraintFamilyId => "transportResourceActivationLink";
18 public override bool IsEnabled(LotSizingInstance instance, StandardLotSizingFormulationOptions options) =>
19 options.IncludeTransport && (options.IncludeResourceActivation || options.IncludeTransportSetups);
20
21 protected override ValueTask BuildConstraintsAsync(LotSizingInstance instance, MathematicalModelBuildContext context,
22 StandardLotSizingFormulationOptions options, CancellationToken cancellationToken)
23 {
24 foreach (var characteristic in instance.SupplyChain.TransportCharacteristics)
25 {
26 var resource = instance.SupplyChain.TransportResources.Single(r => r.Id == characteristic.TransportResourceId);
27 bool activate = options.IncludeResourceActivation && resource.FixedUsageCost is not null;
28 bool setup = options.IncludeTransportSetups && (characteristic.FixedSetupCost is not null || characteristic.SetupTime is not null);
29 if (!activate && !setup) continue;
30 foreach (var lane in instance.SupplyChain.GetTransportLanes(resource.Id))
31 for (int period = 1; period <= instance.PlanningHorizon; period++)
32 {
33 cancellationToken.ThrowIfCancellationRequested();
34 double bound = QuantityBound(resource, characteristic, period, options);
35 var quantity = context.GetVariable(StandardFormulationVariableKeyFactory.CreateTransportKey(
36 characteristic.ItemId, resource.Id, lane.Origin, lane.Destination, period));
37 if (activate)
38 {
42 AddConstraint(context, $"transportResourceActivationLink_i{characteristic.ItemId}_r{resource.Id}_l{lane.Id}_t{period}",
43 new LinearExpressionBuilder().Add(quantity).Subtract(context.GetVariable(key), bound).Build(),
44 MathematicalConstraintSense.LessThanOrEqual, 0, description: "Departure requires the shared resource activation.");
45 }
46 if (setup)
47 {
49 .Add(MathematicalDomainKeySegment.Item, characteristic.ItemId)
53 AddConstraint(context, $"transportSetupLink_i{characteristic.ItemId}_r{resource.Id}_l{lane.Id}_t{period}",
54 new LinearExpressionBuilder().Add(quantity).Subtract(context.GetVariable(key.Add(MathematicalDomainKeySegment.Period, period).Build()), bound).Build(),
55 MathematicalConstraintSense.LessThanOrEqual, 0, description: "Departure requires the existing per-lane item transport setup.");
56 }
57 }
58 }
59 return ValueTask.CompletedTask;
60 }
61
62 private static double QuantityBound(TransportResource resource, TransportCharacteristic characteristic, int period,
64 {
65 double unit = characteristic.UnitCapacityConsumption?[period] ?? 1;
66 double bound = double.PositiveInfinity;
67 if (unit > 0)
68 {
69 if (resource.CapacityConstraint is not null)
70 bound = (resource.CapacityConstraint[period] + (options.IncludeAdditionalCapacity ? resource.AdditionalCapacity?[period] ?? 0 : 0)) / unit;
71 if (characteristic.CapacityConstraint is not null)
72 bound = Math.Min(bound, (characteristic.CapacityConstraint[period] + (options.IncludeAdditionalCapacity ? characteristic.AdditionalCapacity?[period] ?? 0 : 0)) / unit);
73 }
74 if (double.IsFinite(bound)) return bound;
75 return options.TransportActivationBigM ?? throw new InvalidOperationException(
76 $"Transport activation for item {characteristic.ItemId}, resource {resource.Id}, period {period} requires a finite capacity-derived quantity bound or explicit TransportActivationBigM.");
77 }
78}
Provides a fluent builder for linear expressions.
LinearExpression Build(bool clone=true)
Builds and validates the linear expression.
Builds stable business-domain keys for mathematical variables and constraints.
MathematicalDomainKeyBuilder Add(string name, string value)
Adds a text segment.
Provides the shared state required while constructing a solver-independent mathematical model.
Creates canonical domain-key fragments shared by standard formulation builders and provides warehouse...
static MathematicalDomainKeyBuilder AddDestinationWarehouse(MathematicalDomainKeyBuilder builder, WarehouseReference warehouse)
Adds a destination warehouse reference.
static MathematicalDomainKeyBuilder AddOriginWarehouse(MathematicalDomainKeyBuilder builder, WarehouseReference warehouse)
Adds an origin warehouse reference.
Creates canonical variable domain keys used by the standard formulation constraint builders.
static string CreateTransportKey(int itemId, int transportResourceId, WarehouseReference origin, WarehouseReference destination, int period)
Creates a transport quantity decision key.
Provides common validation and helper methods for one constraint family of the standard lot-sizing fo...
static void AddConstraint(MathematicalModelBuildContext context, string name, LinearExpression expression, MathematicalConstraintSense sense, double rightHandSide, string domainKey="", string description="")
Adds one linear constraint to the mathematical model.
Configures the standard solver-independent mixed-integer lot-sizing formulation.
bool IncludeAdditionalCapacity
Gets or sets whether additional capacities are included.
Provides the canonical mathematical domain-key categories used to identify lot-sizing decision famili...
const string TransportSetup
Identifies transport setup decision variables.
const string TransportResourceActivation
Identifies transport-resource activation decision variables.
Provides the canonical mathematical domain-key segment names used by lot-sizing variables and constra...
const string TransportResource
Transport-resource identifier segment.
MathematicalConstraintSense
Identifies the relational sense of a mathematical constraint.