LotSizingDataModel.Core 2.0.1
Core domain model, shared abstractions and XML-serializable entities.
Loading...
Searching...
No Matches
IntegerTimeSeriesParameter.cs
Go to the documentation of this file.
1using System;
2using System.ComponentModel;
3using System.Xml.Serialization;
5
7
8/// <summary>
9/// Base class for decision-model parameters represented by one
10/// integer value for each planning period.
11///
12/// This technical base class centralizes:
13/// - XML serialization;
14/// - planning-horizon resizing;
15/// - change notifications;
16/// - value validation.
17/// </summary>
18[Serializable]
19[XmlType(TypeName = "integerTimeSeriesParameter")]
20public abstract class IntegerTimeSeriesParameter :
23{
24 private IntegerTimeSeries _values = new();
25
26 /// <summary>
27 /// Initializes an empty period-dependent integer parameter.
28 ///
29 /// Derived concrete classes must expose a public
30 /// parameterless constructor for XmlSerializer.
31 /// </summary>
33 {
34 // Subscribe to changes in the values time series
35 SubscribeToValues(_values);
36 }
37
38 /// <summary>
39 /// Initializes a period-dependent integer parameter.
40 /// </summary>
41 /// <param name="planningHorizon">
42 /// Number of periods in the planning horizon.
43 /// </param>
44 /// <param name="defaultValue">
45 /// Initial value assigned to every period.
46 /// </param>
48 int planningHorizon,
49 int defaultValue = 0)
50 : this() // Call default constructor to subscribe to values
51 {
52 // Validate that the planning horizon is non-negative
53 if (planningHorizon < 0)
54 {
55 throw new ArgumentOutOfRangeException(
56 nameof(planningHorizon),
57 planningHorizon,
58 "The planning horizon cannot be negative.");
59 }
60
61 // Validate the default value before applying it to all periods
62 ValidateValue(defaultValue, nameof(defaultValue));
63
64 // Resize the time series to the specified planning horizon
65 Values.Resize(
66 planningHorizon,
67 defaultValue);
68 }
69
70 /// <summary>
71 /// Gets or sets the parameter values for all planning periods.
72 /// </summary>
73 [XmlElement("values")]
75 {
76 get => _values;
77 set
78 {
79 // Ensure the time series is never null
80 IntegerTimeSeries newValue =
81 value ?? new IntegerTimeSeries();
82
83 // Validate all values in the new time series
84 ValidateSeries(newValue);
85
86 // Avoid unnecessary updates if the reference is the same
87 if (ReferenceEquals(_values, newValue))
88 {
89 return;
90 }
91
92 // Unsubscribe from the old time series
93 UnsubscribeFromValues(_values);
94
95 _values = newValue;
96
97 // Subscribe to the new time series
98 SubscribeToValues(_values);
99
100 // Notify dependent properties
101 OnPropertyChanged(nameof(Values));
103 }
104 }
105
106 /// <summary>
107 /// Gets the number of planning periods represented
108 /// by this parameter.
109 /// </summary>
110 [XmlIgnore]
111 public int PlanningHorizon =>
112 Values.PeriodCount;
113
114 /// <summary>
115 /// Gets or sets the parameter value for a planning period.
116 ///
117 /// Planning periods are numbered from 1.
118 /// </summary>
119 [XmlIgnore]
120 public int this[int period]
121 {
122 get => Values[period];
123 set
124 {
125 // Validate the value before setting
126 ValidateValue(value, nameof(value));
127 Values[period] = value;
128 }
129 }
130
131 /// <summary>
132 /// Gets the parameter value for a planning period.
133 /// </summary>
134 public int GetValue(int period)
135 {
136 return this[period];
137 }
138
139 /// <summary>
140 /// Sets the parameter value for a planning period.
141 /// </summary>
142 public void SetValue(
143 int period,
144 int value)
145 {
146 this[period] = value;
147 }
148
149 /// <summary>
150 /// Assigns the same value to every planning period.
151 /// </summary>
152 public void Fill(int value)
153 {
154 // Validate the value before filling all periods
155 ValidateValue(value, nameof(value));
156 Values.Fill(value);
157 }
158
159 /// <summary>
160 /// Resizes the time series when the planning horizon changes.
161 ///
162 /// Existing values are preserved. Newly created periods receive
163 /// <see cref="DefaultValueForNewPeriods"/>.
164 /// </summary>
165 public void ResizeTimeSeries(int periodCount)
166 {
167 // Validate that the period count is non-negative
168 if (periodCount < 0)
169 {
170 throw new ArgumentOutOfRangeException(
171 nameof(periodCount),
172 periodCount,
173 "The planning horizon cannot be negative.");
174 }
175
176 // Resize values with the default value for new periods
177 Values.Resize(
178 periodCount,
180 }
181
182 /// <summary>
183 /// Gets the value assigned to newly created periods
184 /// when the planning horizon grows.
185 /// </summary>
186 [XmlIgnore]
187 protected virtual int DefaultValueForNewPeriods => 0;
188
189 /// <summary>
190 /// Validates one integer value.
191 ///
192 /// The base implementation accepts every integer.
193 /// Derived classes can impose stricter rules.
194 /// </summary>
195 protected virtual void ValidateValue(
196 int value,
197 string parameterName)
198 {
199 // Every value of type int is intrinsically valid here.
200 // Business-specific restrictions are implemented
201 // by derived classes.
202 }
203
204 /// <summary>
205 /// Validates every value contained in a time series.
206 /// </summary>
207 protected void ValidateSeries(
208 IntegerTimeSeries values)
209 {
210 // Ensure the time series is not null
211 ArgumentNullException.ThrowIfNull(values);
212
213 // Validate each value in the time series
214 foreach (int value in values)
215 {
216 ValidateValue(value, nameof(values));
217 }
218 }
219
220 /// <summary>
221 /// Subscribes to property change notifications from the values time series.
222 /// </summary>
223 private void SubscribeToValues(
224 IntegerTimeSeries values)
225 {
226 // Listen to property changes in the time series
227 values.PropertyChanged +=
228 OnValuesPropertyChanged;
229 }
230
231 /// <summary>
232 /// Unsubscribes from property change notifications from the values time series.
233 /// </summary>
234 private void UnsubscribeFromValues(
235 IntegerTimeSeries values)
236 {
237 // Stop listening to property changes in the time series
238 values.PropertyChanged -=
239 OnValuesPropertyChanged;
240 }
241
242 /// <summary>
243 /// Handles property change notifications from the values time series
244 /// and propagates relevant changes to dependent properties.
245 /// </summary>
246 private void OnValuesPropertyChanged(
247 object? sender,
248 PropertyChangedEventArgs e)
249 {
250 // Always notify that Values changed
251 OnPropertyChanged(nameof(Values));
252
253 // Notify dependent properties when period count or values change
254 if (e.PropertyName ==
256 e.PropertyName ==
258 {
260 }
261 }
262}
Represents a sequence of integer values indexed by planning period.
int PeriodCount
Gets the number of planning periods represented by this time series.
int[] Values
Gets or replaces all values of the time series.
Base class for model objects that notify listeners when one of their properties changes.
virtual void OnPropertyChanged([CallerMemberName] string? propertyName=null)
Raises the PropertyChanged event.
int GetValue(int period)
Gets the parameter value for a planning period.
int PlanningHorizon
Gets the number of planning periods represented by this parameter.
void Fill(int value)
Assigns the same value to every planning period.
void ValidateSeries(IntegerTimeSeries values)
Validates every value contained in a time series.
void ResizeTimeSeries(int periodCount)
Resizes the time series when the planning horizon changes.
IntegerTimeSeriesParameter()
Initializes an empty period-dependent integer parameter.
IntegerTimeSeriesParameter(int planningHorizon, int defaultValue=0)
Initializes a period-dependent integer parameter.
void SetValue(int period, int value)
Sets the parameter value for a planning period.
IntegerTimeSeries Values
Gets or sets the parameter values for all planning periods.
virtual void ValidateValue(int value, string parameterName)
Validates one integer value.
virtual int DefaultValueForNewPeriods
Gets the value assigned to newly created periods when the planning horizon grows.
Defines a model object containing data indexed by planning period.