Skip to content

Commit a2b8541

Browse files
committed
update algorithm to deal with the ultra large dataset
1 parent 5ab57ce commit a2b8541

File tree

1 file changed

+83
-54
lines changed

1 file changed

+83
-54
lines changed

Data_science/Mathematica/SignalProcessing/SignalProcessing/KalmanFilter/HungarianAlgorithm.vb

Lines changed: 83 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#End Region
6262

6363
Imports System.Runtime.CompilerServices
64+
Imports Microsoft.VisualBasic.ComponentModel.Collection
6465
Imports Microsoft.VisualBasic.Math.LinearAlgebra.Matrix
6566
Imports std = System.Math
6667

@@ -97,19 +98,19 @@ Namespace HungarianAlgorithm
9798
''' is the column of the task assigned to agent <em>i</em>.</returns>
9899
''' <exception cref="ArgumentNullException"><paramref name="costs"/> is null.</exception>
99100
<Extension()>
100-
Public Function FindAssignments(costs As Double(,)) As Integer()
101-
Dim h = costs.GetLength(0)
102-
Dim w = costs.GetLength(1)
101+
Public Function FindAssignments(costs As Double()()) As Integer()
102+
Dim h = costs.Length
103+
Dim w = costs(0).Length
103104
Dim rowsGreaterThanCols = h > w
104105

105106
If rowsGreaterThanCols Then
106107
' make sure cost matrix has number of rows greater than columns
107108
Dim row = w
108109
Dim col = h
109-
Dim transposeCosts = New Double(row - 1, col - 1) {}
110+
Dim transposeCosts As Double()() = RectangularArray.Matrix(Of Double)(row, col)
110111
For i As Integer = 0 To row - 1
111112
For j As Integer = 0 To col - 1
112-
transposeCosts(i, j) = costs(j, i)
113+
transposeCosts(i)(j) = costs(j)(i)
113114
Next
114115
Next
115116
costs = transposeCosts
@@ -121,22 +122,22 @@ Namespace HungarianAlgorithm
121122
Dim min As Double = Double.MaxValue
122123

123124
For j As Integer = 0 To w - 1
124-
min = std.Min(min, costs(i, j))
125+
min = std.Min(min, costs(i)(j))
125126
Next
126127

127128
For j As Integer = 0 To w - 1
128-
costs(i, j) -= min
129+
costs(i)(j) -= min
129130
Next
130131
Next
131132

132-
Dim masks = New Byte(h - 1, w - 1) {}
133+
Dim masks As Byte()() = RectangularArray.Matrix(Of Byte)(h, w)
133134
Dim rowsCovered = New Boolean(h - 1) {}
134135
Dim colsCovered = New Boolean(w - 1) {}
135136

136137
For i As Integer = 0 To h - 1
137138
For j As Integer = 0 To w - 1
138-
If costs(i, j) = 0.0 AndAlso Not rowsCovered(i) AndAlso Not colsCovered(j) Then
139-
masks(i, j) = 1
139+
If costs(i)(j) = 0.0 AndAlso Not rowsCovered(i) AndAlso Not colsCovered(j) Then
140+
masks(i)(j) = 1
140141
rowsCovered(i) = True
141142
colsCovered(j) = True
142143
End If
@@ -145,8 +146,8 @@ Namespace HungarianAlgorithm
145146

146147
Call ClearCovers(rowsCovered, colsCovered, w, h)
147148

148-
Dim path = New Location(w * h - 1) {}
149-
Dim pathStart As Location = Nothing
149+
Dim path = New(row As Integer, column As Integer)(w * h - 1) {}
150+
Dim pathStart As (row As Integer, column As Integer) = Nothing
150151
Dim [step] = 1
151152

152153
While [step] <> -1
@@ -167,7 +168,7 @@ Namespace HungarianAlgorithm
167168

168169
For i As Integer = 0 To h - 1
169170
For j As Integer = 0 To w - 1
170-
If masks(i, j) = 1 Then
171+
If masks(i)(j) = 1 Then
171172
agentsTasks(i) = j
172173
Exit For
173174
Else
@@ -191,10 +192,10 @@ Namespace HungarianAlgorithm
191192
Return agentsTasks
192193
End Function
193194

194-
Private Function RunStep1(masks As Byte(,), colsCovered As Boolean(), w As Integer, h As Integer) As Integer
195+
Private Function RunStep1(ByRef masks As Byte()(), ByRef colsCovered As Boolean(), w As Integer, h As Integer) As Integer
195196
For i As Integer = 0 To h - 1
196197
For j As Integer = 0 To w - 1
197-
If masks(i, j) = 1 Then colsCovered(j) = True
198+
If masks(i)(j) = 1 Then colsCovered(j) = True
198199
Next
199200
Next
200201

@@ -209,14 +210,19 @@ Namespace HungarianAlgorithm
209210
Return 2
210211
End Function
211212

212-
Private Function RunStep2(costs As Double(,), masks As Byte(,), rowsCovered As Boolean(), colsCovered As Boolean(), w As Integer, h As Integer, ByRef pathStart As Location) As Integer
213+
Private Function RunStep2(ByRef costs As Double()(),
214+
ByRef masks As Byte()(),
215+
ByRef rowsCovered As Boolean(),
216+
ByRef colsCovered As Boolean(),
217+
w As Integer, h As Integer,
218+
ByRef pathStart As (row As Integer, column As Integer)) As Integer
213219
While True
214220
Dim loc = FindZero(costs, rowsCovered, colsCovered, w, h)
215221

216222
If loc.row = -1 Then
217223
Return 4
218224
Else
219-
masks(loc.row, loc.column) = 2
225+
masks(loc.row)(loc.column) = 2
220226
End If
221227

222228
Dim starCol = FindStarInRow(masks, w, loc.row)
@@ -233,7 +239,13 @@ Namespace HungarianAlgorithm
233239
Throw New Exception("never!")
234240
End Function
235241

236-
Private Function RunStep3(masks As Byte(,), rowsCovered As Boolean(), colsCovered As Boolean(), w As Integer, h As Integer, path As Location(), pathStart As Location) As Integer
242+
Private Function RunStep3(ByRef masks As Byte()(),
243+
ByRef rowsCovered As Boolean(),
244+
ByRef colsCovered As Boolean(),
245+
w As Integer, h As Integer,
246+
path As (row As Integer, column As Integer)(),
247+
pathStart As (row As Integer, column As Integer)) As Integer
248+
237249
Dim pathIndex As Integer = 0
238250
path(0) = pathStart
239251

@@ -242,12 +254,12 @@ Namespace HungarianAlgorithm
242254
If row = -1 Then Exit While
243255

244256
pathIndex += 1
245-
path(pathIndex) = New Location(row, path(pathIndex - 1).column)
257+
path(pathIndex) = (row, path(pathIndex - 1).column)
246258

247259
Dim col = FindPrimeInRow(masks, w, path(pathIndex).row)
248260

249261
pathIndex += 1
250-
path(pathIndex) = New Location(path(pathIndex - 1).row, col)
262+
path(pathIndex) = (path(pathIndex - 1).row, col)
251263
End While
252264

253265
ConvertPath(masks, path, pathIndex + 1)
@@ -257,93 +269,121 @@ Namespace HungarianAlgorithm
257269
Return 1
258270
End Function
259271

260-
Private Function RunStep4(costs As Double(,), rowsCovered As Boolean(), colsCovered As Boolean(), w As Integer, h As Integer) As Integer
261-
Dim minValue = FindMinimum(costs, rowsCovered, colsCovered, w, h)
272+
Private Function RunStep4(ByRef costs As Double()(),
273+
ByRef rowsCovered As Boolean(),
274+
ByRef colsCovered As Boolean(),
275+
w As Integer, h As Integer) As Integer
276+
277+
Dim minValue As Double = FindMinimum(costs, rowsCovered, colsCovered, w, h)
262278

263279
For i As Integer = 0 To h - 1
264280
For j As Integer = 0 To w - 1
265-
If rowsCovered(i) Then costs(i, j) += minValue
266-
If Not colsCovered(j) Then costs(i, j) -= minValue
281+
If rowsCovered(i) Then
282+
costs(i)(j) += minValue
283+
End If
284+
If Not colsCovered(j) Then
285+
costs(i)(j) -= minValue
286+
End If
267287
Next
268288
Next
269289

270290
Return 2
271291
End Function
272292

273-
Private Function FindMinimum(costs As Double(,), rowsCovered As Boolean(), colsCovered As Boolean(), w As Integer, h As Integer) As Double
293+
Private Function FindMinimum(ByRef costs As Double()(),
294+
ByRef rowsCovered As Boolean(),
295+
ByRef colsCovered As Boolean(),
296+
w As Integer, h As Integer) As Double
297+
274298
Dim minValue = Double.MaxValue
275299

276300
For i As Integer = 0 To h - 1
277301
For j As Integer = 0 To w - 1
278302
If Not rowsCovered(i) AndAlso Not colsCovered(j) Then
279-
minValue = std.Min(minValue, costs(i, j))
303+
minValue = std.Min(minValue, costs(i)(j))
280304
End If
281305
Next
282306
Next
283307

284308
Return minValue
285309
End Function
286310

287-
Private Function FindStarInRow(masks As Byte(,), w As Integer, row As Integer) As Integer
311+
Private Function FindStarInRow(ByRef masks As Byte()(), w As Integer, row As Integer) As Integer
288312
For j As Integer = 0 To w - 1
289-
If masks(row, j) = 1 Then Return j
313+
If masks(row)(j) = 1 Then
314+
Return j
315+
End If
290316
Next
291317

292318
Return -1
293319
End Function
294320

295-
Private Function FindStarInColumn(masks As Byte(,), h As Integer, col As Integer) As Integer
321+
Private Function FindStarInColumn(ByRef masks As Byte()(), h As Integer, col As Integer) As Integer
296322
For i As Integer = 0 To h - 1
297-
If masks(i, col) = 1 Then Return i
323+
If masks(i)(col) = 1 Then
324+
Return i
325+
End If
298326
Next
299327

300328
Return -1
301329
End Function
302330

303-
Private Function FindPrimeInRow(masks As Byte(,), w As Integer, row As Integer) As Integer
331+
Private Function FindPrimeInRow(ByRef masks As Byte()(), w As Integer, row As Integer) As Integer
304332
For j As Integer = 0 To w - 1
305-
If masks(row, j) = 2 Then Return j
333+
If masks(row)(j) = 2 Then
334+
Return j
335+
End If
306336
Next
307337

308338
Return -1
309339
End Function
310340

311-
Private Function FindZero(costs As Double(,), rowsCovered As Boolean(), colsCovered As Boolean(), w As Integer, h As Integer) As Location
341+
Private Function FindZero(ByRef costs As Double()(),
342+
ByRef rowsCovered As Boolean(),
343+
ByRef colsCovered As Boolean(), w As Integer, h As Integer) As (row As Integer, column As Integer)
344+
312345
For i As Integer = 0 To h - 1
313346
For j As Integer = 0 To w - 1
314-
If costs(i, j) = 0.0 AndAlso Not rowsCovered(i) AndAlso Not colsCovered(j) Then
315-
Return New Location(i, j)
347+
If costs(i)(j) = 0.0 AndAlso Not rowsCovered(i) AndAlso Not colsCovered(j) Then
348+
Return (i, j)
316349
End If
317350
Next
318351
Next
319352

320-
Return New Location(-1, -1)
353+
Return (-1, -1)
321354
End Function
322355

323-
Private Sub ConvertPath(masks As Byte(,), path As Location(), pathLength As Integer)
356+
Private Sub ConvertPath(ByRef masks As Byte()(),
357+
ByRef path As (row As Integer, column As Integer)(),
358+
pathLength As Integer)
359+
324360
For i As Integer = 0 To pathLength - 1
325-
Dim x = masks(path(i).row, path(i).column)
361+
Dim x = masks(path(i).row)(path(i).column)
326362

327363
Select Case x
328364
Case 1
329365
x = 0
330366
Case 2
331367
x = 1
332368
Case Else
333-
x = masks(path(i).row, path(i).column)
369+
x = masks(path(i).row)(path(i).column)
334370
End Select
335371

336-
masks(path(i).row, path(i).column) = x
372+
masks(path(i).row)(path(i).column) = x
337373
Next
338374
End Sub
339-
Private Sub ClearPrimes(masks As Byte(,), w As Integer, h As Integer)
375+
376+
Private Sub ClearPrimes(ByRef masks As Byte()(), w As Integer, h As Integer)
340377
For i As Integer = 0 To h - 1
341378
For j As Integer = 0 To w - 1
342-
If masks(i, j) = 2 Then masks(i, j) = 0
379+
If masks(i)(j) = 2 Then
380+
masks(i)(j) = 0
381+
End If
343382
Next
344383
Next
345384
End Sub
346-
Private Sub ClearCovers(rowsCovered As Boolean(), colsCovered As Boolean(), w As Integer, h As Integer)
385+
386+
Private Sub ClearCovers(ByRef rowsCovered As Boolean(), ByRef colsCovered As Boolean(), w As Integer, h As Integer)
347387
For i As Integer = 0 To h - 1
348388
rowsCovered(i) = False
349389
Next
@@ -352,16 +392,5 @@ Namespace HungarianAlgorithm
352392
colsCovered(j) = False
353393
Next
354394
End Sub
355-
356-
Private Structure Location
357-
358-
Friend ReadOnly row As Integer
359-
Friend ReadOnly column As Integer
360-
361-
Friend Sub New(row As Integer, col As Integer)
362-
Me.row = row
363-
Me.column = col
364-
End Sub
365-
End Structure
366395
End Module
367396
End Namespace

0 commit comments

Comments
 (0)