@@ -997,7 +997,7 @@ Solution.prototype.generateSolutionSet = function () {
997
997
998
998
var varValue = matrix [ r ] [ rhsColumn ] ;
999
999
solutionSet [ variable . id ] =
1000
- Math . round ( varValue * roundingCoeff ) / roundingCoeff ;
1000
+ Math . round ( ( Number . EPSILON + varValue ) * roundingCoeff ) / roundingCoeff ;
1001
1001
}
1002
1002
1003
1003
return solutionSet ;
@@ -1116,6 +1116,8 @@ Tableau.prototype.initialize = function (width, height, variables, unrestrictedV
1116
1116
this . width = width ;
1117
1117
this . height = height ;
1118
1118
1119
+
1120
+ // console.time("tableau_build");
1119
1121
// BUILD AN EMPTY ARRAY OF THAT WIDTH
1120
1122
var tmpRow = new Array ( width ) ;
1121
1123
for ( var i = 0 ; i < width ; i ++ ) {
@@ -1128,6 +1130,17 @@ Tableau.prototype.initialize = function (width, height, variables, unrestrictedV
1128
1130
this . matrix [ j ] = tmpRow . slice ( ) ;
1129
1131
}
1130
1132
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
+
1131
1144
this . varIndexByRow = new Array ( this . height ) ;
1132
1145
this . varIndexByCol = new Array ( this . width ) ;
1133
1146
@@ -1247,7 +1260,7 @@ Tableau.prototype.setEvaluation = function () {
1247
1260
var roundingCoeff = Math . round ( 1 / this . precision ) ;
1248
1261
var evaluation = this . matrix [ this . costRowIndex ] [ this . rhsColumn ] ;
1249
1262
var roundedEvaluation =
1250
- Math . round ( evaluation * roundingCoeff ) / roundingCoeff ;
1263
+ Math . round ( ( Number . EPSILON + evaluation ) * roundingCoeff ) / roundingCoeff ;
1251
1264
1252
1265
this . evaluation = roundedEvaluation ;
1253
1266
if ( this . simplexIters === 0 ) {
@@ -2003,7 +2016,7 @@ Tableau.prototype.updateVariableValues = function () {
2003
2016
} else {
2004
2017
// Variable is basic
2005
2018
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 ;
2007
2020
}
2008
2021
}
2009
2022
} ;
@@ -2564,15 +2577,24 @@ Tableau.prototype.phase1 = function () {
2564
2577
var iterations = 0 ;
2565
2578
2566
2579
while ( true ) {
2580
+ // ******************************************
2581
+ // ** PHASE 1 - STEP 1 : FIND PIVOT ROW **
2582
+ //
2567
2583
// Selecting leaving variable (feasibility condition):
2568
2584
// Basic variable with most negative value
2585
+ //
2586
+ // ******************************************
2569
2587
var leavingRowIndex = 0 ;
2570
2588
var rhsValue = - this . precision ;
2571
2589
for ( var r = 1 ; r <= lastRow ; r ++ ) {
2572
2590
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
+ //}
2576
2598
2577
2599
var value = matrix [ r ] [ rhsColumn ] ;
2578
2600
if ( value < rhsValue ) {
@@ -2588,16 +2610,26 @@ Tableau.prototype.phase1 = function () {
2588
2610
return iterations ;
2589
2611
}
2590
2612
2613
+
2614
+ // ******************************************
2615
+ // ** PHASE 1 - STEP 2 : FIND PIVOT COLUMN **
2616
+ //
2617
+ //
2618
+ // ******************************************
2591
2619
// Selecting entering variable
2592
2620
var enteringColumn = 0 ;
2593
2621
var maxQuotient = - Infinity ;
2594
2622
var costRow = matrix [ 0 ] ;
2595
2623
var leavingRow = matrix [ leavingRowIndex ] ;
2596
2624
for ( var c = 1 ; c <= lastColumn ; c ++ ) {
2597
2625
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
+ //
2601
2633
2602
2634
unrestricted = this . unrestrictedVars [ this . varIndexByCol [ c ] ] === true ;
2603
2635
if ( unrestricted || coefficient < - this . precision ) {
@@ -2801,6 +2833,8 @@ Tableau.prototype.phase2 = function () {
2801
2833
// on the pivot row
2802
2834
// Shared by all tableaux for smaller overhead and lower memory usage
2803
2835
var nonZeroColumns = [ ] ;
2836
+
2837
+
2804
2838
//-------------------------------------------------------------------
2805
2839
// Description: Execute pivot operations over a 2d array,
2806
2840
// on a given row, and column
@@ -2831,10 +2865,12 @@ Tableau.prototype.pivot = function (pivotRowIndex, pivotColumnIndex) {
2831
2865
var pivotRow = matrix [ pivotRowIndex ] ;
2832
2866
var nNonZeroColumns = 0 ;
2833
2867
for ( var c = 0 ; c <= lastColumn ; c ++ ) {
2834
- if ( pivotRow [ c ] !== 0 ) {
2868
+ if ( ! ( pivotRow [ c ] >= - 1e-16 && pivotRow [ c ] <= 1e-16 ) ) {
2835
2869
pivotRow [ c ] /= quotient ;
2836
2870
nonZeroColumns [ nNonZeroColumns ] = c ;
2837
2871
nNonZeroColumns += 1 ;
2872
+ } else {
2873
+ pivotRow [ c ] = 0 ;
2838
2874
}
2839
2875
}
2840
2876
pivotRow [ pivotColumnIndex ] = 1 / quotient ;
@@ -2845,27 +2881,60 @@ Tableau.prototype.pivot = function (pivotRowIndex, pivotColumnIndex) {
2845
2881
// row by ... yuck... just look below; better explanation later
2846
2882
var coefficient , i , v0 ;
2847
2883
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");
2848
2902
for ( var r = 0 ; r <= lastRow ; r ++ ) {
2849
- var row = matrix [ r ] ;
2850
2903
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
2851
2910
coefficient = row [ pivotColumnIndex ] ;
2911
+
2852
2912
// No point Burning Cycles if
2853
2913
// Zero to the thing
2854
- if ( coefficient !== 0 ) {
2914
+ if ( ! ( coefficient >= - 1e-16 && coefficient <= 1e-16 ) ) {
2855
2915
for ( i = 0 ; i < nNonZeroColumns ; i ++ ) {
2856
2916
c = nonZeroColumns [ i ] ;
2857
2917
// No point in doing math if you're just adding
2858
2918
// Zero to the thing
2859
2919
v0 = pivotRow [ c ] ;
2860
- if ( v0 !== 0 ) {
2920
+ if ( ! ( v0 >= - 1e-16 && v0 <= 1e-16 ) ) {
2861
2921
row [ c ] = row [ c ] - coefficient * v0 ;
2922
+ } else {
2923
+ if ( v0 !== 0 ) {
2924
+ pivotRow [ c ] = 0 ;
2925
+ }
2862
2926
}
2863
2927
}
2864
2928
2865
2929
row [ pivotColumnIndex ] = - coefficient / quotient ;
2930
+ } else {
2931
+ if ( coefficient !== 0 ) {
2932
+ row [ pivotColumnIndex ] = 0 ;
2933
+ }
2866
2934
}
2867
2935
}
2868
2936
}
2937
+ // console.timeEnd("step-2");
2869
2938
2870
2939
var nOptionalObjectives = this . optionalObjectives . length ;
2871
2940
if ( nOptionalObjectives > 0 ) {
@@ -3302,8 +3371,15 @@ var Solver = function () {
3302
3371
3303
3372
// 3.) Load all of the variable values
3304
3373
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
+
3307
3383
} ) ;
3308
3384
3309
3385
return store ;
0 commit comments