Skip to content

Commit 55aa3f4

Browse files
committed
added web-versions
1 parent 7779aa0 commit 55aa3f4

File tree

2 files changed

+182
-30
lines changed

2 files changed

+182
-30
lines changed

prod/solver.js

Lines changed: 91 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,7 @@ Solution.prototype.generateSolutionSet = function () {
997997

998998
var varValue = matrix[r][rhsColumn];
999999
solutionSet[variable.id] =
1000-
Math.round(varValue * roundingCoeff) / roundingCoeff;
1000+
Math.round((Number.EPSILON + varValue) * roundingCoeff) / roundingCoeff;
10011001
}
10021002

10031003
return solutionSet;
@@ -1116,6 +1116,8 @@ Tableau.prototype.initialize = function (width, height, variables, unrestrictedV
11161116
this.width = width;
11171117
this.height = height;
11181118

1119+
1120+
// console.time("tableau_build");
11191121
// BUILD AN EMPTY ARRAY OF THAT WIDTH
11201122
var tmpRow = new Array(width);
11211123
for (var i = 0; i < width; i++) {
@@ -1128,6 +1130,17 @@ Tableau.prototype.initialize = function (width, height, variables, unrestrictedV
11281130
this.matrix[j] = tmpRow.slice();
11291131
}
11301132

1133+
//
1134+
// TODO: Benchmark This
1135+
//this.matrix = new Array(height).fill(0).map(() => new Array(width).fill(0));
1136+
1137+
// console.timeEnd("tableau_build");
1138+
// console.log("height",height);
1139+
// console.log("width",width);
1140+
// console.log("------");
1141+
// console.log("");
1142+
1143+
11311144
this.varIndexByRow = new Array(this.height);
11321145
this.varIndexByCol = new Array(this.width);
11331146

@@ -1247,7 +1260,7 @@ Tableau.prototype.setEvaluation = function () {
12471260
var roundingCoeff = Math.round(1 / this.precision);
12481261
var evaluation = this.matrix[this.costRowIndex][this.rhsColumn];
12491262
var roundedEvaluation =
1250-
Math.round(evaluation * roundingCoeff) / roundingCoeff;
1263+
Math.round((Number.EPSILON + evaluation) * roundingCoeff) / roundingCoeff;
12511264

12521265
this.evaluation = roundedEvaluation;
12531266
if (this.simplexIters === 0) {
@@ -2003,7 +2016,7 @@ Tableau.prototype.updateVariableValues = function () {
20032016
} else {
20042017
// Variable is basic
20052018
var varValue = this.matrix[r][this.rhsColumn];
2006-
variable.value = Math.round(varValue * roundingCoeff) / roundingCoeff;
2019+
variable.value = Math.round((varValue + Number.EPSILON) * roundingCoeff) / roundingCoeff;
20072020
}
20082021
}
20092022
};
@@ -2564,15 +2577,24 @@ Tableau.prototype.phase1 = function () {
25642577
var iterations = 0;
25652578

25662579
while (true) {
2580+
// ******************************************
2581+
// ** PHASE 1 - STEP 1 : FIND PIVOT ROW **
2582+
//
25672583
// Selecting leaving variable (feasibility condition):
25682584
// Basic variable with most negative value
2585+
//
2586+
// ******************************************
25692587
var leavingRowIndex = 0;
25702588
var rhsValue = -this.precision;
25712589
for (var r = 1; r <= lastRow; r++) {
25722590
unrestricted = this.unrestrictedVars[this.varIndexByRow[r]] === true;
2573-
if (unrestricted) {
2574-
continue;
2575-
}
2591+
2592+
//
2593+
// *Don't think this does anything...
2594+
//
2595+
//if (unrestricted) {
2596+
// continue;
2597+
//}
25762598

25772599
var value = matrix[r][rhsColumn];
25782600
if (value < rhsValue) {
@@ -2588,16 +2610,26 @@ Tableau.prototype.phase1 = function () {
25882610
return iterations;
25892611
}
25902612

2613+
2614+
// ******************************************
2615+
// ** PHASE 1 - STEP 2 : FIND PIVOT COLUMN **
2616+
//
2617+
//
2618+
// ******************************************
25912619
// Selecting entering variable
25922620
var enteringColumn = 0;
25932621
var maxQuotient = -Infinity;
25942622
var costRow = matrix[0];
25952623
var leavingRow = matrix[leavingRowIndex];
25962624
for (var c = 1; c <= lastColumn; c++) {
25972625
var coefficient = leavingRow[c];
2598-
if (-this.precision < coefficient && coefficient < this.precision) {
2599-
continue;
2600-
}
2626+
//
2627+
// *Don't think this does anything...
2628+
//
2629+
//if (-this.precision < coefficient && coefficient < this.precision) {
2630+
// continue;
2631+
//}
2632+
//
26012633

26022634
unrestricted = this.unrestrictedVars[this.varIndexByCol[c]] === true;
26032635
if (unrestricted || coefficient < -this.precision) {
@@ -2801,6 +2833,8 @@ Tableau.prototype.phase2 = function () {
28012833
// on the pivot row
28022834
// Shared by all tableaux for smaller overhead and lower memory usage
28032835
var nonZeroColumns = [];
2836+
2837+
28042838
//-------------------------------------------------------------------
28052839
// Description: Execute pivot operations over a 2d array,
28062840
// on a given row, and column
@@ -2831,10 +2865,12 @@ Tableau.prototype.pivot = function (pivotRowIndex, pivotColumnIndex) {
28312865
var pivotRow = matrix[pivotRowIndex];
28322866
var nNonZeroColumns = 0;
28332867
for (var c = 0; c <= lastColumn; c++) {
2834-
if (pivotRow[c] !== 0) {
2868+
if (!(pivotRow[c] >= -1e-16 && pivotRow[c] <= 1e-16)) {
28352869
pivotRow[c] /= quotient;
28362870
nonZeroColumns[nNonZeroColumns] = c;
28372871
nNonZeroColumns += 1;
2872+
} else {
2873+
pivotRow[c] = 0;
28382874
}
28392875
}
28402876
pivotRow[pivotColumnIndex] = 1 / quotient;
@@ -2845,27 +2881,60 @@ Tableau.prototype.pivot = function (pivotRowIndex, pivotColumnIndex) {
28452881
// row by ... yuck... just look below; better explanation later
28462882
var coefficient, i, v0;
28472883
var precision = this.precision;
2884+
2885+
// //////////////////////////////////////
2886+
//
2887+
// This is step 2 of the pivot function.
2888+
// It is, by far, the most expensive piece of
2889+
// this whole process where the code can be optimized (faster code)
2890+
// without changing the whole algorithm (fewer cycles)
2891+
//
2892+
// 1.) For every row but the pivot row
2893+
// 2.) Update each column to
2894+
// a.) itself
2895+
// less
2896+
// b.) active-row's pivot column
2897+
// times
2898+
// c.) whatever-the-hell this is: nonZeroColumns[i]
2899+
//
2900+
// //////////////////////////////////////
2901+
// console.time("step-2");
28482902
for (var r = 0; r <= lastRow; r++) {
2849-
var row = matrix[r];
28502903
if (r !== pivotRowIndex) {
2904+
2905+
// Set reference to the row we're working on
2906+
//
2907+
var row = matrix[r];
2908+
2909+
// Catch the coefficient that we're going to end up dividing everything by
28512910
coefficient = row[pivotColumnIndex];
2911+
28522912
// No point Burning Cycles if
28532913
// Zero to the thing
2854-
if (coefficient !== 0) {
2914+
if (!(coefficient >= -1e-16 && coefficient <= 1e-16)) {
28552915
for (i = 0; i < nNonZeroColumns; i++) {
28562916
c = nonZeroColumns[i];
28572917
// No point in doing math if you're just adding
28582918
// Zero to the thing
28592919
v0 = pivotRow[c];
2860-
if (v0 !== 0) {
2920+
if (!(v0 >= -1e-16 && v0 <= 1e-16)) {
28612921
row[c] = row[c] - coefficient * v0;
2922+
} else {
2923+
if(v0 !== 0){
2924+
pivotRow[c] = 0;
2925+
}
28622926
}
28632927
}
28642928

28652929
row[pivotColumnIndex] = -coefficient / quotient;
2930+
} else {
2931+
if(coefficient !== 0){
2932+
row[pivotColumnIndex] = 0;
2933+
}
28662934
}
28672935
}
28682936
}
2937+
// console.timeEnd("step-2");
28692938

28702939
var nOptionalObjectives = this.optionalObjectives.length;
28712940
if (nOptionalObjectives > 0) {
@@ -3302,8 +3371,15 @@ var Solver = function () {
33023371

33033372
// 3.) Load all of the variable values
33043373
Object.keys(solution.solutionSet)
3305-
.map(function (d) {
3306-
store[d] = solution.solutionSet[d];
3374+
.forEach(function (d) {
3375+
//
3376+
// When returning data in standard format,
3377+
// Remove all 0's
3378+
//
3379+
if(solution.solutionSet[d] !== 0){
3380+
store[d] = solution.solutionSet[d];
3381+
}
3382+
33073383
});
33083384

33093385
return store;

0 commit comments

Comments
 (0)