11import { DoubleArray } from 'cheminfo-types' ;
2- import Matrix from 'ml-matrix' ;
3- import sequentialFill from 'ml-array-sequential-fill' ;
2+ import { Matrix } from 'ml-matrix' ;
3+
4+ import { getShortestPath } from './getShortestPath' ;
45
5- let matrix = [ [ 0.1 , 1.1 , 2.1 ] , [ 1.1 , 0.1 , 1.1 ] , [ 2.1 , 1.1 , 0.1 ] ]
6- let assignment = assign2D ( matrix , false ) ;
7- console . log ( assignment )
86export function assign2D ( input : DoubleArray [ ] , maximaze = true ) {
97 if ( input [ 0 ] . length > input . length ) {
108 throw new Error ( 'the matrix should have at least less rows than columns' ) ;
@@ -24,8 +22,8 @@ export function assign2D(input: DoubleArray[], maximaze = true) {
2422 let matrixDelta = maximaze ? matrix . max ( ) : matrix . min ( ) ;
2523 matrix = matrix . subtract ( matrixDelta ) ;
2624
27- let col4row : DoubleArray = new Float64Array ( nbRows ) ;
28- let row4col : DoubleArray = new Float64Array ( nbColumns ) ;
25+ let rowAssignments : DoubleArray = new Float64Array ( nbRows ) . fill ( - 1 ) ;
26+ let columnAssignments : DoubleArray = new Float64Array ( nbColumns ) . fill ( - 1 ) ;
2927 let dualVariableForColumns : DoubleArray = new Float64Array ( nbColumns ) ;
3028 let dualVariableForRows : DoubleArray = new Float64Array ( nbRows ) ;
3129
@@ -35,149 +33,50 @@ export function assign2D(input: DoubleArray[], maximaze = true) {
3533 currUnAssCol,
3634 dualVariableForColumns,
3735 dualVariableForRows,
38- col4row ,
39- row4col ,
36+ rowAssignments ,
37+ columnAssignments ,
4038 } ) ;
4139
4240 let { sink, pred } = currentAugmenting ;
43- console . log ( 'pred' , pred )
41+
4442 if ( sink === - 1 ) {
4543 return {
46- col4row : [ ] ,
47- row4col : [ ] ,
44+ rowAssignments : [ ] ,
45+ columnAssignments : [ ] ,
4846 gain : - 1 ,
4947 }
5048 }
5149
5250 dualVariableForColumns = currentAugmenting . dualVariableForColumns ;
5351 dualVariableForRows = currentAugmenting . dualVariableForRows ;
5452
55- console . log ( dualVariableForColumns , dualVariableForRows )
5653 let j = sink ;
57- console . log ( JSON . stringify ( sink ) ) ;
58- console . log ( `j ${ j } , currUnAssCol ${ currUnAssCol } ` )
5954 for ( let i = pred [ j ] ; true ; i = pred [ j ] ) {
60- col4row [ j ] = i ;
61- let h = row4col [ i ] ;
62- row4col [ i ] = j ;
55+ rowAssignments [ j ] = i ;
56+ let h = columnAssignments [ i ] ;
57+ columnAssignments [ i ] = j ;
6358 j = h ;
6459 if ( i === currUnAssCol ) break ;
6560 }
66- console . log ( JSON . stringify ( { j, sink} ) ) ;
6761 }
6862
6963 let gain = 0 ;
7064 for ( let curCol = 0 ; curCol < nbColumns ; curCol ++ ) {
71- gain += matrix . get ( row4col [ curCol ] , curCol ) ;
65+ gain += matrix . get ( columnAssignments [ curCol ] , curCol ) ;
7266 }
7367
7468 gain = ( ( maximaze ? - 1 : 1 ) * gain ) + ( matrixDelta * nbColumns ) ;
7569
7670 if ( didFlip ) {
77- [ row4col , col4row ] = [ col4row , row4col ] ;
71+ [ columnAssignments , rowAssignments ] = [ rowAssignments , columnAssignments ] ;
7872 [ dualVariableForColumns , dualVariableForRows ] = [ dualVariableForRows , dualVariableForColumns ] ;
7973 }
8074
8175 return {
82- col4row ,
83- row4col ,
76+ rowAssignments ,
77+ columnAssignments ,
8478 gain,
8579 dualVariableForColumns,
8680 dualVariableForRows
8781 }
88- }
89-
90- interface GetShortestPathOptions {
91- currUnAssCol : number ,
92- dualVariableForColumns : DoubleArray ,
93- dualVariableForRows : DoubleArray ,
94- col4row : DoubleArray ,
95- row4col : DoubleArray ,
96- matrix : Matrix ,
97- }
98-
99- function getShortestPath ( options : GetShortestPathOptions ) {
100- let {
101- currUnAssCol,
102- dualVariableForColumns,
103- dualVariableForRows,
104- col4row,
105- row4col,
106- matrix,
107- } = options ;
108-
109- let nbRows = matrix . rows
110- let nbColumns = matrix . columns ;
111-
112- let pred = new Float64Array ( nbColumns ) ;
113- let scannedColumns = new Float64Array ( nbColumns ) ;
114- let scannedRows = new Float64Array ( nbRows ) ;
115-
116- let rows2Scan = sequentialFill ( { from : 0 , to : nbRows - 1 , size : nbRows } ) ;
117- let numRows2Scan = nbRows ;
118-
119- let sink = - 1 ;
120- let delta = 0 ;
121- let curColumn = currUnAssCol ;
122- let shortestPathCost = getArrayOfInfinity ( nbRows ) ;
123-
124- for ( ; sink === - 1 ; ) {
125- scannedColumns [ curColumn ] = 1 ;
126- let minVal = Number . POSITIVE_INFINITY ;
127- let closestRowScan = - 1 ;
128- for ( let curRowScan = 0 ; curRowScan < numRows2Scan ; curRowScan ++ ) {
129- let curRow = rows2Scan [ curRowScan ] ;
130- // console.log(`curRow ${curRow}, ${curRowScan}`)
131- let reducedCost = delta + matrix . get ( curRow , curColumn ) - dualVariableForColumns [ curColumn ] - dualVariableForRows [ curRow ] ;
132- console . log ( 'reduced cost' , reducedCost , curColumn , shortestPathCost [ curRow ] )
133- if ( reducedCost < shortestPathCost [ curRow ] ) {
134- pred [ curRow ] = curColumn ;
135- shortestPathCost [ curRow ] = reducedCost
136- }
137-
138- if ( shortestPathCost [ curRow ] < minVal ) {
139- minVal = shortestPathCost [ curRow ] ;
140- closestRowScan = curRowScan ;
141- }
142- }
143- if ( ! Number . isFinite ( minVal ) ) {
144- return { dualVariableForColumns, dualVariableForRows, sink, pred } ;
145- }
146- let closestRow = rows2Scan [ closestRowScan ] ;
147- scannedRows [ closestRow ] = 1 ;
148- numRows2Scan -= 1 ;
149- rows2Scan . splice ( closestRowScan , 1 ) ;
150- delta = shortestPathCost [ closestRow ] ;
151-
152- if ( col4row [ closestRow ] === 0 ) {
153- sink = closestRow ;
154- } else {
155- curColumn = col4row [ closestRow ] ;
156- }
157- console . log ( `sink ${ sink } ` ) ;
158- }
159- console . log ( 'sale loop sink' )
160- dualVariableForColumns [ currUnAssCol ] += delta ;
161-
162- for ( let sel = 0 ; sel < nbColumns ; sel ++ ) {
163- if ( scannedColumns [ sel ] === 0 ) continue ;
164- if ( sel === currUnAssCol ) continue ;
165- dualVariableForColumns [ sel ] += delta - shortestPathCost [ row4col [ sel ] ] ;
166- }
167- for ( let sel = 0 ; sel < nbRows ; sel ++ ) {
168- if ( scannedRows [ sel ] === 0 ) continue ;
169- dualVariableForRows [ sel ] -= ( delta - shortestPathCost [ sel ] ) ;
170- }
171- console . log ( 'return' )
172- return {
173- sink, pred, dualVariableForColumns, dualVariableForRows
174- }
175- }
176-
177- function getArrayOfInfinity ( nbElements = 1 , value = Number . POSITIVE_INFINITY ) {
178- const array = new Array ( nbElements ) ;
179- for ( let i = 0 ; i < nbElements ; i ++ ) {
180- array [ i ] = value ;
181- }
182- return array ;
18382}
0 commit comments