-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathalternateSoln.js
136 lines (118 loc) · 4.88 KB
/
alternateSoln.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
* Check if any element in specified A column is positve.
*
* @param A 2d LHS constraint array (after simplex has been applied).
* @param b 1d array of solution values.
* @param Idx Column Idx.
* @return Row in A[][Idx] with lowest positive b/col ratio, Boolean
* indicating whether there's a positive, finite ratio.
*/
function AColPos(A, b, Idx) {
// Initialize relevant variables
var min = Number.POSITIVE_INFINITY;
var k = -1;
// Search through each row in A in the specified column for a positive
// element.
for (let i = 0; i < A.length; i++) {
if ((floatCor(A[i][Idx]) > 0) && (b[i]/A[i][Idx] < min)) {
min = b[i]/A[i][Idx];
k = i;
}
}
// k != -1 tests whether a positive ratio was found
if (k != -1) {
return [k, true];
} else {
return [k, false];
}
}
/**
* Check for alternate solutions and mention it in tempStr if there is.
*
* @param A 2d array of LHS coefficients.
* @param b 1d array of solution values.
* @param cj 1d array of objective function coefficients.
* @param x 1d array of decision variables.
* @param xB 1d array of basis variables.
* @param zmn Objective function value.
* @param zc 1d array of zj-cj values.
* @param sign What the objective function has been multiplied by to make
* it a maximization problem.
* @param objVarName Objective function name (e.g. z).
* @return Nothing, writes to tempStr.
*/
function checkForAltSol(A, b, cj, x, xB, zmn, zc, sign, objVarName) {
// Dimensions of the problem
var {m, mn, n} = getDims(A);
// Counter of how many variables able to depart are found
var arrOfPivIdxs = genArrPivIdxs(A, b, x, xB, zc, mn);
var k = arrOfPivIdxs.length;
// If k != 0, alternate solutions must exist.
if (k != 0) {
tempStr += "Alternate solution(s) exists. ";
for (let i = 0; i < k; i++) {
// Determine pivot indices
var [pivColIdx, pivRowIdx] = arrOfPivIdxs[i];
// Find ratios for b to pivot column
var {pivCol, ratio} = findColRat(A, b, pivColIdx);
// Determine the pivot element
var pivEl = A[pivRowIdx][pivColIdx];
// Define vars for genTableau
var format = {isBold: false, isLeftArrow: false,
isDownArrow: false, notRow: true};
var bools = {isFeas: true, isOptim: true, isUnbounded: false,
isPermInf: false, isAltSol: false, befAltSol: true};
// Say let this var exit and the other var enter on a new line
tempStr += "<br/>";
tempStr += "Let " + subscripts(xB[pivRowIdx], format) + " exit the basis and ";
tempStr += subscripts(x[pivColIdx], format) + " enter it. ";
// Generate tableau showing the entering/leaving vars
genTableau(A, b, cj, x, xB, bools, pivCol, ratio, pivEl,
pivRowIdx, pivColIdx);
// Show row operations
rowOperations(pivRowIdx, pivCol, pivEl);
// Perform row operations
[A, b, xB] = rowOps(A, b, x, xB, pivColIdx, pivRowIdx, pivEl,
pivCol, mn, m);
// Generate tableau of alternate solution
bools.isAltSol = true;
bools.befAltSol = false;
genTableau(A, b, cj, x, xB, bools, pivCol, ratio, pivEl,
pivRowIdx, pivColIdx);
tempStr += "Which gives the solution: ";
// Print alternate solution
printSolution(b, xB, x, zc, zmn, mn, n, sign, objVarName, true);
checkForDegn(b, xB);
}
}
}
/**
* Generate array of pivot indices for alternate solutions.
*
* @param A 2d array of LHS coefficients.
* @param b 1d array of solution values.
* @param x 1d array of decision variables.
* @param xB 1d array of basis variables.
* @param zc 1d array of zj-cj values.
* @param mn Number of columns in A.
* @return Array of pivot indices (row nad column).
*/
function genArrPivIdxs(A, b, x, xB, zc, mn) {
// Initialize array of pivot indices
var arrOfPivIdxs = [];
// Loop over each element in zc looking for zc = 0 for a non-basis variable
for (let i = 0; i < mn; i++) {
// A correction to prevent floating-point errors from messing up
// following comparison
var zcCor = floatCor(zc[i]);
// zj-cj must equal zero for non-basis variable column and the column
// must have a positive aij value.
if (!find(xB, x[i]) && (zcCor == 0) && AColPos(A, b, i)[1]) {
// Display message in HTML to indicate which variable can enter
// the basis.
var pivRowIdx = AColPos(A, b, i)[0];
arrOfPivIdxs.push([i, pivRowIdx]);
}
}
return arrOfPivIdxs;
}