LotSizingDataModel.Instance 2.0.1
Lot-sizing instance representation, descriptors and problem characterization.
Loading...
Searching...
No Matches
LotSizingProblemClassification.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Xml.Serialization;
5using LotSizingDataModel.Core.Common;
7
9
10/// <summary>
11/// Stores the persistent result of the automatic
12/// classification of a lot-sizing problem instance.
13/// </summary>
14/// <remarks>
15/// A classification contains the factual feature profile,
16/// all detected known-problem-family matches and an optional
17/// primary family selected by the classifier.
18///
19/// The classification also records the supply-chain
20/// fingerprint, classifier version and catalog version used
21/// to produce the result.
22/// </remarks>
23[Serializable]
24[XmlType(TypeName = "lotSizingProblemClassification")]
25public sealed class LotSizingProblemClassification :
26 ModelObject
27{
28 private ProblemClassificationStatus _status =
30
31 private LotSizingProblemFeatures _features =
32 new();
33
34 private string _primaryProblemTypeCode =
35 string.Empty;
36
37 private string _primaryProblemTypeName =
38 string.Empty;
39
40 private string _classifierVersion =
41 string.Empty;
42
43 private string _catalogName =
44 string.Empty;
45
46 private string _catalogVersion =
47 string.Empty;
48
49 private DateTime? _classifiedAtUtc;
50
51 private string _supplyChainFingerprint =
52 string.Empty;
53
54 private string _comment =
55 string.Empty;
56
57 /// <summary>
58 /// Initializes an empty lot-sizing problem
59 /// classification.
60 /// </summary>
61 /// <remarks>
62 /// This constructor is required for XML serialization.
63 /// </remarks>
67
68 /// <summary>
69 /// Initializes a lot-sizing problem classification with
70 /// an extracted feature profile.
71 /// </summary>
72 /// <param name="features">
73 /// Factual features extracted from the supply-chain
74 /// instance.
75 /// </param>
78 {
79 ArgumentNullException.ThrowIfNull(features);
80
81 Features = features;
82 }
83
84 /// <summary>
85 /// Gets or sets the current global classification status.
86 /// </summary>
87 [XmlAttribute("status")]
89 {
90 get => _status;
91 set
92 {
93 if (SetProperty(
94 ref _status,
95 value))
96 {
97 NotifyDerivedProperties();
98 }
99 }
100 }
101
102 /// <summary>
103 /// Gets or sets the factual lot-sizing problem features
104 /// used during classification.
105 /// </summary>
106 [XmlElement("features")]
108 {
109 get => _features;
110 set
111 {
112 LotSizingProblemFeatures normalizedValue =
113 value ??
115
116 if (SetProperty(
117 ref _features,
118 normalizedValue))
119 {
120 OnPropertyChanged(
121 nameof(HasUsableFeatures));
122
123 OnPropertyChanged(
125 }
126 }
127 }
128
129 /// <summary>
130 /// Gets or sets the stable code of the primary recognized
131 /// problem family.
132 /// </summary>
133 /// <remarks>
134 /// The value is empty when no unique primary family has
135 /// been selected.
136 /// </remarks>
137 [XmlAttribute("primaryProblemTypeCode")]
139 {
140 get => _primaryProblemTypeCode;
141 set
142 {
143 if (SetProperty(
144 ref _primaryProblemTypeCode,
145 NormalizeProblemTypeCode(value)))
146 {
147 NotifyPrimaryMatchProperties();
148 }
149 }
150 }
151
152 /// <summary>
153 /// Gets or sets the human-readable name of the primary
154 /// recognized problem family.
155 /// </summary>
156 [XmlAttribute("primaryProblemTypeName")]
158 {
159 get => _primaryProblemTypeName;
160 set
161 {
162 if (SetProperty(
163 ref _primaryProblemTypeName,
164 value?.Trim() ?? string.Empty))
165 {
166 NotifyPrimaryMatchProperties();
167 }
168 }
169 }
170
171 /// <summary>
172 /// Gets or sets the version of the software classifier
173 /// that produced this result.
174 /// </summary>
175 [XmlAttribute("classifierVersion")]
176 public string ClassifierVersion
177 {
178 get => _classifierVersion;
179 set
180 {
181 if (SetProperty(
182 ref _classifierVersion,
183 value?.Trim() ?? string.Empty))
184 {
185 OnPropertyChanged(
186 nameof(HasClassifierVersion));
187 }
188 }
189 }
190
191 /// <summary>
192 /// Gets or sets the human-readable name of the
193 /// problem-type catalog used during classification.
194 /// </summary>
195 [XmlAttribute("catalogName")]
196 public string CatalogName
197 {
198 get => _catalogName;
199 set
200 {
201 if (SetProperty(
202 ref _catalogName,
203 value?.Trim() ?? string.Empty))
204 {
205 OnPropertyChanged(
206 nameof(HasCatalogInformation));
207 }
208 }
209 }
210
211 /// <summary>
212 /// Gets or sets the version of the problem-type catalog
213 /// used during classification.
214 /// </summary>
215 [XmlAttribute("catalogVersion")]
216 public string CatalogVersion
217 {
218 get => _catalogVersion;
219 set
220 {
221 if (SetProperty(
222 ref _catalogVersion,
223 value?.Trim() ?? string.Empty))
224 {
225 OnPropertyChanged(
226 nameof(HasCatalogInformation));
227 }
228 }
229 }
230
231 /// <summary>
232 /// Gets or sets the UTC date and time at which the
233 /// classification was produced.
234 /// </summary>
235 /// <remarks>
236 /// A null value means that no completed classification
237 /// date has been recorded.
238 /// </remarks>
239 [XmlElement("classifiedAtUtc", IsNullable = true)]
240 public DateTime? ClassifiedAtUtc
241 {
242 get => _classifiedAtUtc;
243 set
244 {
245 DateTime? utcValue =
246 value.HasValue
247 ? ConvertToUtc(value.Value)
248 : null;
249
250 if (SetProperty(
251 ref _classifiedAtUtc,
252 utcValue))
253 {
254 OnPropertyChanged(
255 nameof(HasBeenAnalyzed));
256 }
257 }
258 }
259
260 /// <summary>
261 /// Gets or sets the fingerprint of the supply-chain data
262 /// used to produce this classification.
263 /// </summary>
264 /// <remarks>
265 /// The fingerprint allows validation services to detect
266 /// that the supply chain has changed after classification.
267 /// </remarks>
268 [XmlAttribute("supplyChainFingerprint")]
270 {
271 get => _supplyChainFingerprint;
272 set
273 {
274 if (SetProperty(
275 ref _supplyChainFingerprint,
276 value?.Trim() ?? string.Empty))
277 {
278 OnPropertyChanged(
280 }
281 }
282 }
283
284 /// <summary>
285 /// Gets all known-problem-family matches detected for
286 /// the analyzed instance.
287 /// </summary>
288 /// <remarks>
289 /// The collection may contain complete-problem matches,
290 /// relaxations, subproblems and closest-family matches.
291 /// </remarks>
292 [XmlArray("matches")]
293 [XmlArrayItem("knownProblemTypeMatch")]
294 public List<KnownProblemTypeMatch> Matches { get; } =
295 new();
296
297 /// <summary>
298 /// Gets the codes of detected features that are not
299 /// adequately represented by any reported family match.
300 /// </summary>
301 /// <remarks>
302 /// These codes help distinguish a fully classified
303 /// problem from a partially classified extension.
304 /// </remarks>
305 [XmlArray("unclassifiedFeatureCodes")]
306 [XmlArrayItem("featureCode")]
307 public List<string> UnclassifiedFeatureCodes { get; } =
308 new();
309
310 /// <summary>
311 /// Gets the warnings produced during feature extraction
312 /// or problem classification.
313 /// </summary>
314 [XmlArray("warnings")]
315 [XmlArrayItem("warning")]
316 public List<string> Warnings { get; } =
317 new();
318
319 /// <summary>
320 /// Gets the errors produced during feature extraction or
321 /// problem classification.
322 /// </summary>
323 [XmlArray("errors")]
324 [XmlArrayItem("error")]
325 public List<string> Errors { get; } =
326 new();
327
328 /// <summary>
329 /// Gets or sets an optional human-readable comment about
330 /// the complete classification.
331 /// </summary>
332 [XmlElement("comment")]
333 public string Comment
334 {
335 get => _comment;
336 set
337 {
338 if (SetProperty(
339 ref _comment,
340 value?.Trim() ?? string.Empty))
341 {
342 OnPropertyChanged(
343 nameof(HasComment));
344 }
345 }
346 }
347
348 /// <summary>
349 /// Gets a value indicating whether the extracted feature
350 /// profile contains the minimum information required by
351 /// the classifier.
352 /// </summary>
353 [XmlIgnore]
354 public bool HasUsableFeatures =>
355 Features.IsStructurallyUsable;
356
357 /// <summary>
358 /// Gets a value indicating whether a primary
359 /// problem-family code has been selected.
360 /// </summary>
361 [XmlIgnore]
363 !string.IsNullOrWhiteSpace(
365
366 /// <summary>
367 /// Gets a value indicating whether the primary
368 /// problem-family name has been recorded.
369 /// </summary>
370 [XmlIgnore]
372 !string.IsNullOrWhiteSpace(
374
375 /// <summary>
376 /// Gets a value indicating whether the classifier
377 /// version has been recorded.
378 /// </summary>
379 [XmlIgnore]
380 public bool HasClassifierVersion =>
381 !string.IsNullOrWhiteSpace(
383
384 /// <summary>
385 /// Gets a value indicating whether both catalog name and
386 /// catalog version have been recorded.
387 /// </summary>
388 [XmlIgnore]
390 !string.IsNullOrWhiteSpace(
391 CatalogName) &&
392 !string.IsNullOrWhiteSpace(
394
395 /// <summary>
396 /// Gets a value indicating whether a supply-chain
397 /// fingerprint has been recorded.
398 /// </summary>
399 [XmlIgnore]
401 !string.IsNullOrWhiteSpace(
403
404 /// <summary>
405 /// Gets a value indicating whether a completed analysis
406 /// date has been recorded.
407 /// </summary>
408 [XmlIgnore]
409 public bool HasBeenAnalyzed =>
410 ClassifiedAtUtc.HasValue;
411
412 /// <summary>
413 /// Gets a value indicating whether an explanatory comment
414 /// has been recorded.
415 /// </summary>
416 [XmlIgnore]
417 public bool HasComment =>
418 !string.IsNullOrWhiteSpace(
419 Comment);
420
421 /// <summary>
422 /// Gets the total number of reported problem-family
423 /// matches.
424 /// </summary>
425 [XmlIgnore]
426 public int MatchCount =>
427 Matches.Count;
428
429 /// <summary>
430 /// Gets the number of direct exact or known-extension
431 /// matches without blocking conditions.
432 /// </summary>
433 [XmlIgnore]
434 public int DirectMatchCount =>
435 Matches.Count(
436 match =>
437 match is not null &&
438 match.IsDirectMatch);
439
440 /// <summary>
441 /// Gets the number of exact matches.
442 /// </summary>
443 [XmlIgnore]
444 public int ExactMatchCount =>
445 Matches.Count(
446 match =>
447 match is not null &&
448 match.IsExactMatch &&
449 !match.HasBlockingMismatches);
450
451 /// <summary>
452 /// Gets the number of recognized relaxations.
453 /// </summary>
454 [XmlIgnore]
456 Matches.Count(
457 match =>
458 match is not null &&
459 match.MatchKind ==
460 ProblemMatchKind.RecognizedRelaxation);
461
462 /// <summary>
463 /// Gets the number of recognized subproblems.
464 /// </summary>
465 [XmlIgnore]
467 Matches.Count(
468 match =>
469 match is not null &&
470 match.MatchKind ==
471 ProblemMatchKind.RecognizedSubproblem);
472
473 /// <summary>
474 /// Gets a value indicating whether at least one
475 /// problem-family match has been reported.
476 /// </summary>
477 [XmlIgnore]
478 public bool HasMatches =>
479 MatchCount > 0;
480
481 /// <summary>
482 /// Gets a value indicating whether at least one direct
483 /// known-family match has been reported.
484 /// </summary>
485 [XmlIgnore]
486 public bool HasDirectMatches =>
488
489 /// <summary>
490 /// Gets a value indicating whether unclassified features
491 /// remain after classification.
492 /// </summary>
493 [XmlIgnore]
495 UnclassifiedFeatureCodes.Count > 0;
496
497 /// <summary>
498 /// Gets a value indicating whether at least one warning
499 /// was produced.
500 /// </summary>
501 [XmlIgnore]
502 public bool HasWarnings =>
503 Warnings.Count > 0;
504
505 /// <summary>
506 /// Gets a value indicating whether at least one error
507 /// was produced.
508 /// </summary>
509 [XmlIgnore]
510 public bool HasErrors =>
511 Errors.Count > 0;
512
513 /// <summary>
514 /// Gets a value indicating whether the stored
515 /// classification is marked as outdated.
516 /// </summary>
517 [XmlIgnore]
518 public bool IsOutdated =>
519 Status ==
521
522 /// <summary>
523 /// Gets a value indicating whether classification failed
524 /// because the analyzed instance was invalid.
525 /// </summary>
526 [XmlIgnore]
527 public bool IsInvalid =>
528 Status ==
530
531 /// <summary>
532 /// Gets a value indicating whether the classification can
533 /// currently contribute to method selection.
534 /// </summary>
535 /// <remarks>
536 /// A partially classified or ambiguous instance may still
537 /// provide useful matches, provided that at least one
538 /// direct match exists and the stored result is neither
539 /// invalid nor outdated.
540 /// </remarks>
541 [XmlIgnore]
545 !HasErrors &&
546 (
547 Status ==
549 Status ==
551 .PartiallyClassified ||
552 Status ==
554 );
555
556 /// <summary>
557 /// Gets the match corresponding to the selected primary
558 /// problem-family code.
559 /// </summary>
560 /// <remarks>
561 /// Complete-problem direct matches are preferred when
562 /// several matches use the same family code.
563 /// </remarks>
564 [XmlIgnore]
566 {
567 get
568 {
570 {
571 return null;
572 }
573
574 return Matches
575 .Where(
576 match =>
577 match is not null &&
578 string.Equals(
579 match.ProblemTypeCode,
581 StringComparison.OrdinalIgnoreCase))
582 .OrderByDescending(
583 match =>
584 match.AppliesToCompleteProblem)
585 .ThenByDescending(
586 match =>
587 match.IsDirectMatch)
588 .ThenByDescending(
589 match =>
590 match.Score)
591 .FirstOrDefault();
592 }
593 }
594
595 /// <summary>
596 /// Adds one known-problem-family match.
597 /// </summary>
598 /// <param name="match">
599 /// Match to add.
600 /// </param>
601 public void AddMatch(
603 {
604 ArgumentNullException.ThrowIfNull(match);
605
606 Matches.Add(match);
607
608 NotifyMatchProperties();
609 }
610
611 /// <summary>
612 /// Replaces all known-problem-family matches.
613 /// </summary>
614 /// <param name="matches">
615 /// New match collection.
616 /// </param>
617 /// <exception cref="ArgumentException">
618 /// Thrown when the collection contains a null element.
619 /// </exception>
620 public void ReplaceMatches(
621 IEnumerable<KnownProblemTypeMatch> matches)
622 {
623 ArgumentNullException.ThrowIfNull(matches);
624
625 KnownProblemTypeMatch[] normalizedMatches =
626 matches.ToArray();
627
628 if (normalizedMatches.Any(
629 match =>
630 match is null))
631 {
632 throw new ArgumentException(
633 "The match collection cannot contain a " +
634 "null element.",
635 nameof(matches));
636 }
637
638 Matches.Clear();
639 Matches.AddRange(normalizedMatches);
640
641 NotifyMatchProperties();
642 }
643
644 /// <summary>
645 /// Removes all known-problem-family matches and clears the
646 /// selected primary family.
647 /// </summary>
648 public void ClearMatches()
649 {
650 Matches.Clear();
651
653
654 NotifyMatchProperties();
655 }
656
657 /// <summary>
658 /// Selects one existing match as the primary recognized
659 /// problem family.
660 /// </summary>
661 /// <param name="match">
662 /// Match to select.
663 /// </param>
664 /// <exception cref="InvalidOperationException">
665 /// Thrown when the supplied match is not contained in the
666 /// current classification.
667 /// </exception>
668 public void SetPrimaryMatch(
670 {
671 ArgumentNullException.ThrowIfNull(match);
672
673 if (!Matches.Contains(match))
674 {
675 throw new InvalidOperationException(
676 "The primary match must belong to the " +
677 "classification match collection.");
678 }
679
680 if (string.IsNullOrWhiteSpace(
681 match.ProblemTypeCode))
682 {
683 throw new InvalidOperationException(
684 "The primary match must have a known " +
685 "problem-type code.");
686 }
687
689 match.ProblemTypeCode;
690
692 match.ProblemTypeName;
693 }
694
695 /// <summary>
696 /// Removes the currently selected primary
697 /// problem-family information.
698 /// </summary>
700 {
702 string.Empty;
703
705 string.Empty;
706 }
707
708 /// <summary>
709 /// Replaces the globally unclassified feature codes.
710 /// </summary>
711 /// <param name="featureCodes">
712 /// Feature codes not covered by the reported matches.
713 /// </param>
715 IEnumerable<string> featureCodes)
716 {
717 ReplaceNormalizedStrings(
719 featureCodes,
720 nameof(featureCodes));
721
722 OnPropertyChanged(
724
725 OnPropertyChanged(
727 }
728
729 /// <summary>
730 /// Replaces all classification warnings.
731 /// </summary>
732 /// <param name="warnings">
733 /// Warning messages.
734 /// </param>
735 public void ReplaceWarnings(
736 IEnumerable<string> warnings)
737 {
738 ReplaceNormalizedStrings(
739 Warnings,
740 warnings,
741 nameof(warnings));
742
743 OnPropertyChanged(
744 nameof(Warnings));
745
746 OnPropertyChanged(
747 nameof(HasWarnings));
748 }
749
750 /// <summary>
751 /// Replaces all classification errors.
752 /// </summary>
753 /// <param name="errors">
754 /// Error messages.
755 /// </param>
756 public void ReplaceErrors(
757 IEnumerable<string> errors)
758 {
759 ReplaceNormalizedStrings(
760 Errors,
761 errors,
762 nameof(errors));
763
764 OnPropertyChanged(
765 nameof(Errors));
766
767 OnPropertyChanged(
768 nameof(HasErrors));
769
770 OnPropertyChanged(
772 }
773
774 /// <summary>
775 /// Determines whether the stored classification was
776 /// produced from the supplied supply-chain fingerprint.
777 /// </summary>
778 /// <param name="currentFingerprint">
779 /// Current supply-chain fingerprint.
780 /// </param>
781 /// <returns>
782 /// <see langword="true"/> when both fingerprints are
783 /// present and equal; otherwise, <see langword="false"/>.
784 /// </returns>
786 string currentFingerprint)
787 {
788 if (string.IsNullOrWhiteSpace(
789 currentFingerprint) ||
791 {
792 return false;
793 }
794
795 return string.Equals(
797 currentFingerprint.Trim(),
798 StringComparison.Ordinal);
799 }
800
801 /// <summary>
802 /// Marks the stored classification as outdated.
803 /// </summary>
804 /// <remarks>
805 /// Existing features, matches and evidence are preserved
806 /// for traceability but must not be used until the
807 /// instance is classified again.
808 /// </remarks>
809 public void MarkAsOutdated()
810 {
811 if (Status ==
812 ProblemClassificationStatus.NotAnalyzed ||
813 Status ==
815 {
816 return;
817 }
818
819 Status =
821 }
822
823 /// <summary>
824 /// Clears all generated classification information while
825 /// preserving the current feature object.
826 /// </summary>
828 {
829 Matches.Clear();
831 Warnings.Clear();
832 Errors.Clear();
833
835 string.Empty;
836
838 string.Empty;
839
841 string.Empty;
842
844 string.Empty;
845
847 string.Empty;
848
850 null;
851
853 string.Empty;
854
855 Comment =
856 string.Empty;
857
858 Status =
859 ProblemClassificationStatus.NotAnalyzed;
860
861 NotifyMatchProperties();
862
863 OnPropertyChanged(
865
866 OnPropertyChanged(
867 nameof(Warnings));
868
869 OnPropertyChanged(
870 nameof(Errors));
871
872 NotifyDerivedProperties();
873 }
874
875 /// <inheritdoc/>
876 public override string ToString()
877 {
878 string primaryDescription =
881 : "no primary family";
882
883 return
884 $"{Status}; {primaryDescription}; " +
885 $"{MatchCount} match(es)";
886 }
887
888 private static string NormalizeProblemTypeCode(
889 string? value)
890 {
891 return value?
892 .Trim()
893 .ToUpperInvariant() ??
894 string.Empty;
895 }
896
897 private static void ReplaceNormalizedStrings(
898 ICollection<string> destination,
899 IEnumerable<string> source,
900 string parameterName)
901 {
902 ArgumentNullException.ThrowIfNull(source);
903
904 string[] normalizedValues =
905 source
906 .Where(
907 value =>
908 !string.IsNullOrWhiteSpace(
909 value))
910 .Select(
911 value =>
912 value.Trim())
913 .Distinct(
914 StringComparer.OrdinalIgnoreCase)
915 .OrderBy(
916 value =>
917 value,
918 StringComparer.OrdinalIgnoreCase)
919 .ToArray();
920
921 destination.Clear();
922
923 foreach (string value in normalizedValues)
924 {
925 destination.Add(value);
926 }
927 }
928
929 private static DateTime ConvertToUtc(
930 DateTime value)
931 {
932 return value.Kind switch
933 {
934 DateTimeKind.Utc =>
935 value,
936
937 DateTimeKind.Local =>
938 value.ToUniversalTime(),
939
940 _ =>
941 DateTime.SpecifyKind(
942 value,
943 DateTimeKind.Utc)
944 };
945 }
946
947 private void NotifyPrimaryMatchProperties()
948 {
949 OnPropertyChanged(
950 nameof(HasPrimaryProblemType));
951
952 OnPropertyChanged(
954
955 OnPropertyChanged(
956 nameof(PrimaryMatch));
957
958 OnPropertyChanged(
960 }
961
962 private void NotifyMatchProperties()
963 {
964 OnPropertyChanged(
965 nameof(Matches));
966
967 OnPropertyChanged(
968 nameof(MatchCount));
969
970 OnPropertyChanged(
971 nameof(DirectMatchCount));
972
973 OnPropertyChanged(
974 nameof(ExactMatchCount));
975
976 OnPropertyChanged(
977 nameof(RelaxationMatchCount));
978
979 OnPropertyChanged(
980 nameof(SubproblemMatchCount));
981
982 OnPropertyChanged(
983 nameof(HasMatches));
984
985 OnPropertyChanged(
986 nameof(HasDirectMatches));
987
988 OnPropertyChanged(
989 nameof(PrimaryMatch));
990
991 OnPropertyChanged(
993 }
994
995 private void NotifyDerivedProperties()
996 {
997 OnPropertyChanged(
998 nameof(IsOutdated));
999
1000 OnPropertyChanged(
1001 nameof(IsInvalid));
1002
1003 OnPropertyChanged(
1005 }
1006}
Represents a detected correspondence between a lot-sizing instance and a known problem family.
string ProblemTypeName
Gets or sets the human-readable name of the known lot-sizing problem family.
string ProblemTypeCode
Gets or sets the stable code identifying the known lot-sizing problem family.
void ClearMatches()
Removes all known-problem-family matches and clears the selected primary family.
void ReplaceErrors(IEnumerable< string > errors)
Replaces all classification errors.
bool HasClassifierVersion
Gets a value indicating whether the classifier version has been recorded.
bool HasComment
Gets a value indicating whether an explanatory comment has been recorded.
bool HasSupplyChainFingerprint
Gets a value indicating whether a supply-chain fingerprint has been recorded.
bool HasWarnings
Gets a value indicating whether at least one warning was produced.
bool HasCatalogInformation
Gets a value indicating whether both catalog name and catalog version have been recorded.
string CatalogName
Gets or sets the human-readable name of the problem-type catalog used during classification.
KnownProblemTypeMatch? PrimaryMatch
Gets the match corresponding to the selected primary problem-family code.
void SetPrimaryMatch(KnownProblemTypeMatch match)
Selects one existing match as the primary recognized problem family.
int DirectMatchCount
Gets the number of direct exact or known-extension matches without blocking conditions.
LotSizingProblemFeatures Features
Gets or sets the factual lot-sizing problem features used during classification.
bool HasUnclassifiedFeatures
Gets a value indicating whether unclassified features remain after classification.
void ClearClassificationResult()
Clears all generated classification information while preserving the current feature object.
bool HasPrimaryProblemTypeName
Gets a value indicating whether the primary problem-family name has been recorded.
void AddMatch(KnownProblemTypeMatch match)
Adds one known-problem-family match.
string CatalogVersion
Gets or sets the version of the problem-type catalog used during classification.
void ReplaceUnclassifiedFeatureCodes(IEnumerable< string > featureCodes)
Replaces the globally unclassified feature codes.
void ClearPrimaryProblemType()
Removes the currently selected primary problem-family information.
bool HasUsableFeatures
Gets a value indicating whether the extracted feature profile contains the minimum information requir...
bool CanBeUsedForMethodSelection
Gets a value indicating whether the classification can currently contribute to method selection.
string Comment
Gets or sets an optional human-readable comment about the complete classification.
bool MatchesSupplyChainFingerprint(string currentFingerprint)
Determines whether the stored classification was produced from the supplied supply-chain fingerprint.
List< string > Warnings
Gets the warnings produced during feature extraction or problem classification.
LotSizingProblemClassification(LotSizingProblemFeatures features)
Initializes a lot-sizing problem classification with an extracted feature profile.
int MatchCount
Gets the total number of reported problem-family matches.
bool HasErrors
Gets a value indicating whether at least one error was produced.
bool HasMatches
Gets a value indicating whether at least one problem-family match has been reported.
LotSizingProblemClassification()
Initializes an empty lot-sizing problem classification.
List< KnownProblemTypeMatch > Matches
Gets all known-problem-family matches detected for the analyzed instance.
List< string > Errors
Gets the errors produced during feature extraction or problem classification.
void ReplaceMatches(IEnumerable< KnownProblemTypeMatch > matches)
Replaces all known-problem-family matches.
string ClassifierVersion
Gets or sets the version of the software classifier that produced this result.
string SupplyChainFingerprint
Gets or sets the fingerprint of the supply-chain data used to produce this classification.
void ReplaceWarnings(IEnumerable< string > warnings)
Replaces all classification warnings.
bool HasBeenAnalyzed
Gets a value indicating whether a completed analysis date has been recorded.
string PrimaryProblemTypeName
Gets or sets the human-readable name of the primary recognized problem family.
ProblemClassificationStatus Status
Gets or sets the current global classification status.
bool HasDirectMatches
Gets a value indicating whether at least one direct known-family match has been reported.
bool HasPrimaryProblemType
Gets a value indicating whether a primary problem-family code has been selected.
List< string > UnclassifiedFeatureCodes
Gets the codes of detected features that are not adequately represented by any reported family match.
string PrimaryProblemTypeCode
Gets or sets the stable code of the primary recognized problem family.
bool IsOutdated
Gets a value indicating whether the stored classification is marked as outdated.
DateTime? ClassifiedAtUtc
Gets or sets the UTC date and time at which the classification was produced.
bool IsInvalid
Gets a value indicating whether classification failed because the analyzed instance was invalid.
Describes the factual structural and modeling features detected in a lot-sizing supply-chain instance...
ProblemMatchKind
Identifies how a supply-chain instance matches a known lot-sizing problem family.
ProblemClassificationStatus
Indicates the current status of the automatic classification of a lot-sizing problem instance.
@ Ambiguous
Several known problem families match the instance equally well and no unique primary classification c...
@ Classified
The complete problem has been associated with a known lot-sizing family or with a clearly identified ...