@@ -21,16 +21,21 @@ func (g *adjacencyMatrixResidual) init() *adjacencyMatrixResidual {
21
21
func (g * adjacencyMatrixResidual ) AddEdgeWithFlow (e edge , f int ) {
22
22
g .adjacencyMatrixWithFlow .AddEdgeWithFlow (e , f )
23
23
if g .RCap (e ) == 0 {
24
- g .DeleteEdge (e )
24
+ //delete edge but keep cap and flow, because if residual flow (RCap) change, this edge should be added back
25
+ g .adjacencyMatrix .DeleteEdge (e )
25
26
}
26
27
}
27
28
28
29
func (g * adjacencyMatrixResidual ) RCap (e edge ) int {
29
30
return g .Cap (e ) - g .Flow (e )
30
31
}
31
32
32
- func newResidualGraph () residualGraph {
33
- return new (adjacencyMatrixResidual ).init ()
33
+ func newResidualGraph (g flowGraph ) residualGraph {
34
+ residualG := new (adjacencyMatrixResidual ).init ()
35
+ for _ , e := range g .AllEdges () {
36
+ residualG .AddEdgeWithCap (e , g .Cap (e ))
37
+ }
38
+ return residualG
34
39
}
35
40
36
41
func augmentingPath (g residualGraph , s interface {}, t interface {}) (int , []edge ) {
@@ -64,20 +69,135 @@ func updateFlow(rg residualGraph, g flowGraph, rc int, edges []edge) {
64
69
}
65
70
}
66
71
67
- func edmondsKarp (g flowGraph , s interface {}, t interface {}) {
68
- residualG := newResidualGraph ()
69
- for _ , e := range g .AllEdges () {
70
- g .AddEdgeWithFlow (e , 0 )
71
- residualG .AddEdgeWithCap (e , g .Cap (e ))
72
- }
72
+ func edmondesKarp (g flowGraph , s interface {}, t interface {}) {
73
+ residualG := newResidualGraph (g )
73
74
74
75
for rc , edges := augmentingPath (residualG , s , t ); len (edges ) > 0 ; rc , edges = augmentingPath (residualG , s , t ) {
75
76
updateFlow (residualG , g , rc , edges )
76
77
}
77
78
78
79
}
79
80
80
- func bioGraphMaxMatch (g graph , l []interface {}) graph {
81
+ type preFlowGraph interface {
82
+ residualGraph
83
+ SetHeight (interface {}, int )
84
+ SetExcess (interface {}, int )
85
+ Height (interface {}) int
86
+ Excess (interface {}) int
87
+ Push (edge ) bool
88
+ Relabel (interface {}) bool
89
+ Overflow (interface {}) bool
90
+ }
91
+
92
+ type adjacencyMatrixPreFlow struct {
93
+ adjacencyMatrixResidual
94
+ height , excess map [interface {}]int
95
+ s , t interface {}
96
+ }
97
+
98
+ func (g * adjacencyMatrixPreFlow ) init (s , t interface {}) * adjacencyMatrixPreFlow {
99
+ g .adjacencyMatrixResidual .init ()
100
+ g .height = make (map [interface {}]int )
101
+ g .excess = make (map [interface {}]int )
102
+ g .s = s
103
+ g .t = t
104
+ return g
105
+ }
106
+
107
+ func (g * adjacencyMatrixPreFlow ) SetHeight (v interface {}, h int ) {
108
+ g .height [v ] = h
109
+ }
110
+
111
+ func (g * adjacencyMatrixPreFlow ) Height (v interface {}) int {
112
+ if _ , ok := g .height [v ]; ! ok {
113
+ return 0
114
+ }
115
+ return g .height [v ]
116
+ }
117
+
118
+ func (g * adjacencyMatrixPreFlow ) SetExcess (v interface {}, e int ) {
119
+ g .excess [v ] = e
120
+ }
121
+
122
+ func (g * adjacencyMatrixPreFlow ) Excess (v interface {}) int {
123
+ if _ , ok := g .excess [v ]; ! ok {
124
+ return 0
125
+ }
126
+ return g .excess [v ]
127
+ }
128
+
129
+ func (g * adjacencyMatrixPreFlow ) Push (e edge ) bool {
130
+ if g .Overflow (e .Start ) && g .RCap (e ) > 0 && g .Height (e .Start ) == g .Height (e .End )+ 1 {
131
+ d := g .RCap (e )
132
+ if g .Excess (e .Start ) < d {
133
+ d = g .Excess (e .Start )
134
+ }
135
+ flow := g .Flow (e ) + d
136
+ g .AddEdgeWithFlow (e , flow )
137
+ re := edge {e .End , e .Start }
138
+ g .AddEdgeWithFlow (re , 0 - flow )
139
+ g .SetExcess (e .Start , g .Excess (e .Start )- d )
140
+ g .SetExcess (e .End , g .Excess (e .End )+ d )
141
+ return true
142
+ }
143
+ return false
144
+ }
145
+
146
+ func (g * adjacencyMatrixPreFlow ) Relabel (v interface {}) bool {
147
+ if ! g .Overflow (v ) {
148
+ return false
149
+ }
150
+ iter := g .IterConnectedVertices (v )
151
+ minH := math .MaxInt32
152
+ for end := iter .Value (); end != nil ; end = iter .Next () {
153
+ if g .Height (end ) < minH {
154
+ minH = g .Height (end )
155
+ }
156
+ if g .Height (v ) > g .Height (end ) {
157
+ return false
158
+ }
159
+ }
160
+ g .SetHeight (v , minH + 1 )
161
+ return true
162
+ }
163
+
164
+ func (g * adjacencyMatrixPreFlow ) Overflow (v interface {}) bool {
165
+ //According to definition, start and target vertex never overflow
166
+ return v != g .s && v != g .t && g .Excess (v ) > 0
167
+ }
168
+
169
+ func newPreFlowGraph (g flowGraph , s interface {}, t interface {}) preFlowGraph {
170
+ preFlowG := new (adjacencyMatrixPreFlow ).init (s , t )
171
+ vertices := g .AllVertices ()
172
+ for _ , e := range g .AllEdges () {
173
+ preFlowG .AddEdgeWithCap (e , g .Cap (e ))
174
+ }
175
+ preFlowG .SetHeight (s , len (vertices ))
176
+ iter := g .IterConnectedVertices (s )
177
+ for v := iter .Value (); v != nil ; v = iter .Next () {
178
+ c := g .Cap (edge {s , v })
179
+ preFlowG .AddEdgeWithFlow (edge {s , v }, c )
180
+ preFlowG .AddEdgeWithFlow (edge {v , s }, 0 - c )
181
+ preFlowG .SetExcess (v , c )
182
+ preFlowG .SetExcess (s , preFlowG .Excess (s )- c )
183
+ }
184
+ return preFlowG
185
+ }
186
+
187
+ func pushRelabel (g flowGraph , s interface {}, t interface {}) {
188
+ preFlowG := newPreFlowGraph (g , s , t )
189
+ for stop := false ; ! stop ; {
190
+ stop = true
191
+ for _ , e := range preFlowG .AllEdges () {
192
+ stop = stop && ! preFlowG .Push (e ) && ! preFlowG .Relabel (e .Start ) && ! preFlowG .Relabel (e .End )
193
+ }
194
+ }
195
+ for _ , e := range g .AllEdges () {
196
+ g .AddEdgeWithFlow (e , preFlowG .Flow (e ))
197
+ }
198
+ }
199
+
200
+ func bioGraphMaxMatch (g graph , l []interface {}, flowAlg func (g flowGraph , s interface {}, t interface {})) graph {
81
201
//build flow graph
82
202
fG := newFlowGraph ()
83
203
s := struct { start string }{"s" }
@@ -91,7 +211,7 @@ func bioGraphMaxMatch(g graph, l []interface{}) graph {
91
211
}
92
212
}
93
213
94
- edmondsKarp (fG , s , t )
214
+ flowAlg (fG , s , t )
95
215
matchG := newGraph ()
96
216
for _ , e := range fG .AllEdges () {
97
217
if fG .Flow (e ) > 0 && e .Start != s && e .End != t {
0 commit comments