linny-r 1.6.8 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -88,7 +88,6 @@ class LinnyRModel {
88
88
  this.selected_round = 0;
89
89
 
90
90
  // Model settings
91
- this.timeout_period = 30; // max. solver time in seconds
92
91
  this.block_length = 1;
93
92
  this.start_period = 1; // defines starting point in datasets
94
93
  this.end_period = 1;
@@ -99,6 +98,12 @@ class LinnyRModel {
99
98
  this.report_results = false;
100
99
  this.show_block_arrows = true;
101
100
  this.last_zoom_factor = 1;
101
+
102
+ // Default solver settings
103
+ this.timeout_period = 30; // max. solver time in seconds
104
+ this.preferred_solver = ''; // empty string denotes "use default"
105
+ this.integer_tolerance = 5e-7; // integer feasibility tolerance
106
+ this.MIP_gap = 1e-4; // relative MIP gap
102
107
 
103
108
  // Sensitivity-related properties
104
109
  this.base_case_selectors = '';
@@ -140,17 +145,18 @@ class LinnyRModel {
140
145
  /* METHODS THAT LOOKUP ENTITIES, OR INFER PROPERTIES */
141
146
 
142
147
  get simulationTimeStep() {
143
- // Returns actual model time step, rather than `t`, which is relative to the
144
- // start of the simulation period
148
+ // Return actual model time step, rather than `t`, which is relative
149
+ // to the start of the simulation period.
145
150
  return this.t + this.start_period - 1;
146
151
  }
147
152
 
148
153
  get timeStepDuration() {
149
- // Returns duration of 1 time step in hours
154
+ // Return duration of 1 time step in hours.
150
155
  return this.time_scale * VM.time_unit_values[this.time_unit];
151
156
  }
152
157
 
153
158
  get outcomes() {
159
+ // Return the list of outcome datasets.
154
160
  const olist = [];
155
161
  for(let k in this.datasets) if(this.datasets.hasOwnProperty(k)) {
156
162
  if(this.datasets[k].outcome) olist.push(this.datasets[k]);
@@ -2631,17 +2637,17 @@ class LinnyRModel {
2631
2637
  }
2632
2638
 
2633
2639
  initFromXML(node) {
2634
- // Initialize a model from the XML tree with `node` as root
2635
- // NOTE: do NOT reset and initialize basic model properties when *including*
2636
- // a module into the current model
2637
- // NOTE: obsolete XML nodes indicate: legacy Linny-R model
2640
+ // Initialize a model from the XML tree with `node` as root.
2641
+ // NOTE: do NOT reset and initialize basic model properties when
2642
+ // *including* a module into the current model.
2643
+ // NOTE: Obsolete XML nodes indicate: legacy Linny-R model.
2638
2644
  const legacy_model = (nodeParameterValue(node, 'view-options') +
2639
2645
  nodeParameterValue(node, 'autosave') +
2640
2646
  nodeParameterValue(node, 'look-ahead') +
2641
2647
  nodeParameterValue(node, 'save-series') +
2642
2648
  nodeParameterValue(node, 'show-lp') +
2643
2649
  nodeParameterValue(node, 'optional-slack')).length > 0;
2644
- // Flag to set when legacy time series data are added
2650
+ // Flag to set when legacy time series data are added.
2645
2651
  this.legacy_datasets = false;
2646
2652
  if(!IO_CONTEXT) {
2647
2653
  this.reset();
@@ -2668,7 +2674,12 @@ class LinnyRModel {
2668
2674
  this.version = xmlDecoded(nodeContentByTag(node, 'version'));
2669
2675
  this.timeout_period = Math.max(0,
2670
2676
  safeStrToInt(nodeContentByTag(node, 'timeout-period')));
2671
- // Legacy models have tag "optimization-period" instead of "block-length"
2677
+ this.preferred_solver = xmlDecoded(
2678
+ nodeContentByTag(node, 'preferred-solver'));
2679
+ this.integer_tolerance = safeStrToFloat(
2680
+ nodeContentByTag(node, 'integer-tolerance'), 5e-7);
2681
+ this.MIP_gap = safeStrToFloat(nodeContentByTag(node, 'mip-gap'), 1e-4);
2682
+ // Legacy models have tag "optimization-period" instead of "block-length".
2672
2683
  const bl_str = nodeContentByTag(node, 'block-length') ||
2673
2684
  nodeContentByTag(node, 'optimization-period');
2674
2685
  this.block_length = Math.max(1, safeStrToInt(node, bl_str));
@@ -2693,7 +2704,7 @@ class LinnyRModel {
2693
2704
  if(!this.default_unit) this.default_unit = CONFIGURATION.default_scale_unit;
2694
2705
  } // END IF *not* including a model
2695
2706
 
2696
- // Declare some local variables that will be used a lot
2707
+ // Declare some local variables that will be used a lot.
2697
2708
  let i,
2698
2709
  c,
2699
2710
  name,
@@ -3014,7 +3025,10 @@ class LinnyRModel {
3014
3025
  '</default-scale-unit><currency-unit>', xmlEncoded(this.currency_unit),
3015
3026
  '</currency-unit><grid-pixels>', this.grid_pixels,
3016
3027
  '</grid-pixels><timeout-period>', this.timeout_period,
3017
- '</timeout-period><block-length>', this.block_length,
3028
+ '</timeout-period><preferred-solver>', xmlEncoded(this.preferred_solver),
3029
+ '</preferred-solver><integer-tolerance>', this.integer_tolerance,
3030
+ '</integer-tolerance><mip-gap>', this.MIP_gap,
3031
+ '</mip-gap><block-length>', this.block_length,
3018
3032
  '</block-length><start-period>', this.start_period,
3019
3033
  '</start-period><end-period>', this.end_period,
3020
3034
  '</end-period><look-ahead-period>', this.look_ahead,
@@ -7110,24 +7124,24 @@ class Cluster extends NodeBox {
7110
7124
  class Node extends NodeBox {
7111
7125
  constructor(cluster, name, actor) {
7112
7126
  super(cluster, name, actor);
7113
- // Nodes are assigned a unique code as "shorthand notation"
7114
- // NOTE: decimal numbers for processes, Excel-style letter codes for
7127
+ // Nodes are assigned a unique code as "shorthand notation".
7128
+ // NOTE: Decimal numbers for processes, Excel-style letter codes for
7115
7129
  // products, i.e., A, ..., Z, AA, AB, etc.
7116
7130
  this.code = null;
7117
- // By default, nodes are NOT data products (only products can become data!)
7131
+ // By default, nodes are NOT data products (only products can become data).
7118
7132
  this.is_data = false;
7119
- // By default, node levels are continuous, but may be set to integer
7133
+ // By default, node levels are continuous, but may be set to integer.
7120
7134
  this.integer_level = false;
7121
- // Processes and products both have input attributes LB, UB and IL, and
7122
- // result attributes L and CP
7135
+ // Processes and products both have input attributes LB, UB and IL,
7136
+ // and result attributes L and CP.
7123
7137
  this.lower_bound = new Expression(this, 'LB', '');
7124
7138
  this.upper_bound = new Expression(this, 'UB', '');
7125
7139
  this.initial_level = new Expression(this, 'IL', '0');
7126
7140
  this.cost_price = [];
7127
- // NOTE: for processes, level denotes the production level, for products
7128
- // the stock level
7141
+ // NOTE: For processes, level denotes the production level, for products
7142
+ // the stock level.
7129
7143
  this.level = [];
7130
- // `inputs` is array of incoming links, `outputs` is array of outgoing links
7144
+ // `inputs` is array of incoming links, `outputs` is array of outgoing links.
7131
7145
  this.inputs = [];
7132
7146
  this.outputs = [];
7133
7147
  this.predecessors = [];
@@ -7148,13 +7162,13 @@ class Node extends NodeBox {
7148
7162
  }
7149
7163
 
7150
7164
  get hasBounds() {
7151
- // Returns TRUE if lower or upper bound is defined for this node
7165
+ // Return TRUE if lower or upper bound is defined for this node.
7152
7166
  return this.upper_bound.defined || this.lower_bound.defined;
7153
7167
  }
7154
7168
 
7155
7169
  setConstraintOffsets() {
7156
- // Sets the offset properties of the constraints that relate to this
7157
- // node; these properties are used when drawing these constraints.
7170
+ // Set the offset properties of the constraints that relate to this
7171
+ // node. These properties are used when drawing these constraints.
7158
7172
  const tbc = {top: [], bottom: [], thumb: []};
7159
7173
  for(let k in MODEL.constraints) if(MODEL.constraints.hasOwnProperty(k)) {
7160
7174
  const
@@ -7412,14 +7426,14 @@ class Node extends NodeBox {
7412
7426
  }
7413
7427
 
7414
7428
  canConstrain(node) {
7415
- // Returns TRUE if this node can constrain `node`
7416
- // NOTE: A node cannot constrain itself, and BOTH nodes must have upper bounds
7429
+ // Return TRUE if this node can constrain `node`.
7430
+ // NOTE: A node cannot constrain itself, and BOTH nodes must have upper bounds.
7417
7431
  return this !== node && this.upper_bound.defined && node.upper_bound.defined;
7418
7432
  }
7419
7433
 
7420
7434
  get costAddingConstraints() {
7421
- // Returns a (possibly empty) list of composite constraints that can
7422
- // transfer cost to this node
7435
+ // Return a (possibly empty) list of composite constraints that can
7436
+ // transfer cost to this node.
7423
7437
  let cac = [];
7424
7438
  for(let k in MODEL.constraints) if(MODEL.constraints.hasOwnProperty(k)) {
7425
7439
  const c = MODEL.constraints[k];
@@ -7434,7 +7448,7 @@ class Node extends NodeBox {
7434
7448
 
7435
7449
  convertLegacyBoundData(lb_data, ub_data) {
7436
7450
  // Convert time series data for LB and UB in legacy models to datasets,
7437
- // and replace attribute expressions by references to these datasets
7451
+ // and replace attribute expressions by references to these datasets.
7438
7452
  if(!lb_data && !ub_data) return;
7439
7453
  const same = lb_data === ub_data;
7440
7454
  if(lb_data) {
@@ -1076,6 +1076,7 @@ if(NODE) module.exports = {
1076
1076
  msecToTime: msecToTime,
1077
1077
  compactClockTime: compactClockTime,
1078
1078
  uniformDecimals: uniformDecimals,
1079
+ capitalized: capitalized,
1079
1080
  ellipsedText: ellipsedText,
1080
1081
  earlierVersion: earlierVersion,
1081
1082
  differences: differences,
@@ -1083,12 +1084,23 @@ if(NODE) module.exports = {
1083
1084
  ciCompare: ciCompare,
1084
1085
  endsWithDigits: endsWithDigits,
1085
1086
  indexOfMatchingBracket: indexOfMatchingBracket,
1087
+ monoSpaced: monoSpaced,
1088
+ monoSpacedVariables: monoSpacedVariables,
1086
1089
  patternList: patternList,
1087
1090
  patternMatch: patternMatch,
1088
- compareSelectors: compareSelectors,
1089
- stringToFloatArray: stringToFloatArray,
1091
+ matchingWildcardNumber: matchingWildcardNumber,
1090
1092
  escapeRegex: escapeRegex,
1093
+ wildcardMatchRegex: wildcardMatchRegex,
1094
+ wildcardFormat: wildcardFormat,
1095
+ matchingNumber: matchingNumber,
1096
+ matchingNumberInList: matchingNumberInList,
1097
+ compareWithTailNumbers: compareWithTailNumbers,
1098
+ compareSelectors: compareSelectors,
1099
+ compareCombinations: compareCombinations,
1091
1100
  addDistinct: addDistinct,
1101
+ mergeDistinct: mergeDistinct,
1102
+ iteratorSet: iteratorSet,
1103
+ integerSet: integerSet,
1092
1104
  setString: setString,
1093
1105
  tupelString: tupelString,
1094
1106
  tupelSetString: tupelSetString,
@@ -1097,6 +1109,7 @@ if(NODE) module.exports = {
1097
1109
  complement: complement,
1098
1110
  xmlEncoded: xmlEncoded,
1099
1111
  xmlDecoded: xmlDecoded,
1112
+ customizeXML: customizeXML,
1100
1113
  cleanXML: cleanXML,
1101
1114
  parseXML: parseXML,
1102
1115
  childNodeByTag: childNodeByTag,
@@ -1107,12 +1120,16 @@ if(NODE) module.exports = {
1107
1120
  parseLetterCode: parseLetterCode,
1108
1121
  randomID: randomID,
1109
1122
  escapedSingleQuotes: escapedSingleQuotes,
1123
+ safeDoubleQuotes: safeDoubleQuotes,
1110
1124
  nameToLines: nameToLines,
1125
+ hexToFloat: hexToFloat,
1126
+ stringToFloatArray: stringToFloatArray,
1111
1127
  hexToBytes: hexToBytes,
1128
+ bytesToHex: bytesToHex,
1112
1129
  arrayBufferToBase64: arrayBufferToBase64,
1113
1130
  base64ToArrayBuffer: base64ToArrayBuffer,
1114
1131
  encryptionKey: encryptionKey,
1115
1132
  encryptMessage: encryptMessage,
1116
1133
  decryptMessage: decryptMessage,
1117
- tryToDecrypt: tryToDecrypt
1134
+ tryToDecrypt: tryToDecrypt
1118
1135
  }