-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoptimality.js
79 lines (72 loc) · 2.38 KB
/
optimality.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
* Correct floating point numbers that are really integers/fractions
*
* @param number Number to be corrected.
* @return If the number of infinite or undefined, return that,
* otherwise return (hopefully) more accurate version of the number.
*/
function floatCor(number) {
// If number cannot be converted to a fraction, leave as is
if ( ( number == Number.POSITIVE_INFINITY ) || (number == Number.NEGATIVE_INFINITY) || (number == undefined)) {
return number;
}
// Otherwise convert to a fraction and then back to a floating point
// useful for replacing very small positive or negative numbers to 0
else {
var bCor = math.fraction(number);
return bCor.s * bCor.n / bCor.d;
}
}
/**
* Corrects output of minElIfLt0 to account for feasible, but non-optimal
* solutions.
*
* @param b Solution vector as 1d array.
* @param zc zj-cj row of tableau as 1d array.
* @return [minIndex, isFeas, isOptim]
*/
function isOptAndFeas(b, zc) {
// Determine feasibility and relevant associated values is minElIfLt0
var [minIndex, isFeas, isOptim] = minElIfLt0(b);
// If zj-cj < 0 for any j and isOptim is set to true, set isOptim to false
if (isOptim) {
isOptim = !isZcNeg(zc);
}
// Return corrected isOptim and the other outputs of minElIfLt0
return {minIndex: minIndex, isFeas: isFeas, isOptim: isOptim};
}
/**
* Determine whether any value in zc is negative.
*
* @param zc 1d array of zj-cj values.
* @return Boolean reflecting whether any zc entry is negative.
*/
function isZcNeg(zc) {
for (let i = 0; i < zc.length; i++) {
// Ensure that floating point errors do not stuff up determination
// of optimality
if (floatCor(zc[i]) < 0) {
return true;
}
}
// If we get here no negative entries were found
return false;
}
/**
* Determine whether solution is feasible and hence optimum and if infeasible,
* determine minimum element of b and its row index.
*
* @param b 1d array containing the RHS of the constraints.
* @return [minIndex, isFeas, isOptim]
*/
function minElIfLt0(b) {
// Initialize variables
var isFeas = true;
var isOptim = true;
var minIndex = minEl(b, true, false);
if (minIndex != -1) {
isFeas = false;
isOptim = false;
}
return [minIndex, isFeas, isOptim];
}