Skip to content

Commit 327a5d8

Browse files
author
Ubuntu
committed
add relabel to front
1 parent b1887a3 commit 327a5d8

File tree

2 files changed

+93
-16
lines changed

2 files changed

+93
-16
lines changed

graph/flowGraph.go

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package graph
22

33
import (
4+
"container/list"
45
"math"
56
)
67

@@ -95,12 +96,26 @@ type adjacencyMatrixPreFlow struct {
9596
s, t interface{}
9697
}
9798

98-
func (g *adjacencyMatrixPreFlow) init(s, t interface{}) *adjacencyMatrixPreFlow {
99+
func (g *adjacencyMatrixPreFlow) init(fg flowGraph, s, t interface{}) *adjacencyMatrixPreFlow {
99100
g.adjacencyMatrixResidual.init()
100101
g.height = make(map[interface{}]int)
101102
g.excess = make(map[interface{}]int)
102103
g.s = s
103104
g.t = t
105+
106+
vertices := fg.AllVertices()
107+
for _, e := range fg.AllEdges() {
108+
g.AddEdgeWithCap(e, fg.Cap(e))
109+
}
110+
g.SetHeight(s, len(vertices))
111+
iter := fg.IterConnectedVertices(s)
112+
for v := iter.Value(); v != nil; v = iter.Next() {
113+
c := fg.Cap(edge{s, v})
114+
g.AddEdgeWithFlow(edge{s, v}, c)
115+
g.AddEdgeWithFlow(edge{v, s}, 0-c)
116+
g.SetExcess(v, c)
117+
g.SetExcess(s, g.Excess(s)-c)
118+
}
104119
return g
105120
}
106121

@@ -167,21 +182,7 @@ func (g *adjacencyMatrixPreFlow) Overflow(v interface{}) bool {
167182
}
168183

169184
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+
return new(adjacencyMatrixPreFlow).init(g, s, t)
185186
}
186187

187188
func pushRelabel(g flowGraph, s interface{}, t interface{}) {
@@ -197,6 +198,62 @@ func pushRelabel(g flowGraph, s interface{}, t interface{}) {
197198
}
198199
}
199200

201+
type allowedGraph interface {
202+
preFlowGraph
203+
Discharge(interface{})
204+
}
205+
206+
type adjacencyMatrixAllowed struct {
207+
adjacencyMatrixPreFlow
208+
edges graph
209+
}
210+
211+
func (g *adjacencyMatrixAllowed) init(fg flowGraph, s, t interface{}) *adjacencyMatrixAllowed {
212+
g.adjacencyMatrixPreFlow.init(fg, s, t)
213+
g.edges = newGraph()
214+
for _, e := range fg.AllEdges() {
215+
g.edges.AddEdgeBi(e)
216+
}
217+
return g
218+
}
219+
220+
func (g *adjacencyMatrixAllowed) Discharge(v interface{}) {
221+
iter := g.edges.IterConnectedVertices(v)
222+
for g.Overflow(v) {
223+
if iter.Value() == nil {
224+
g.Relabel(v)
225+
iter = g.edges.IterConnectedVertices(v)
226+
} else if !g.Push(edge{v, iter.Value()}) {
227+
iter.Next()
228+
}
229+
}
230+
}
231+
232+
func newAllowedGraph(g flowGraph, s, t interface{}) allowedGraph {
233+
return new(adjacencyMatrixAllowed).init(g, s, t)
234+
}
235+
236+
func relabelToFront(g flowGraph, s interface{}, t interface{}) {
237+
allowedG := newAllowedGraph(g, s, t)
238+
l := list.New()
239+
for _, v := range g.AllVertices() {
240+
if v != s && v != t {
241+
l.PushBack(v)
242+
}
243+
}
244+
for e := l.Front(); e != nil; {
245+
oldH := allowedG.Height(e.Value)
246+
allowedG.Discharge(e.Value)
247+
if allowedG.Height(e.Value) > oldH {
248+
l.MoveToFront(e)
249+
}
250+
e = e.Next()
251+
}
252+
for _, e := range g.AllEdges() {
253+
g.AddEdgeWithFlow(e, allowedG.Flow(e))
254+
}
255+
}
256+
200257
func bioGraphMaxMatch(g graph, l []interface{}, flowAlg func(g flowGraph, s interface{}, t interface{})) graph {
201258
//build flow graph
202259
fG := newFlowGraph()

graph/flowGraph_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ func bioGraphMaxMatchGoldenByPushRelabel() graph {
8484
return g
8585
}
8686

87+
func bioGraphMaxMatchGoldenByRelabelToFront() graph {
88+
g := newGraph()
89+
g.AddEdgeBi(edge{"l0", "r0"})
90+
g.AddEdgeBi(edge{"l1", "r2"})
91+
g.AddEdgeBi(edge{"l2", "r1"})
92+
return g
93+
}
94+
8795
func checkFlowGraphOutOfOrder(t *testing.T, g, gGolden flowGraph) {
8896
comparator := func(t *testing.T, v, vExp []interface{}, e, eExp []edge) {
8997
for _, e := range eExp {
@@ -114,12 +122,24 @@ func TestPushRelabel(t *testing.T) {
114122
checkFlowGraphOutOfOrder(t, g, gGolden)
115123
}
116124

125+
func TestRelabelToFront(t *testing.T) {
126+
g := flowGraphSetup()
127+
relabelToFront(g, "s", "t")
128+
gGolden := pushRelabelGolden(g)
129+
checkFlowGraphOutOfOrder(t, g, gGolden)
130+
}
131+
117132
func TestBioGraphMaxMatch(t *testing.T) {
118133
bioG, l := bioGraphMaxMatchSetup()
119134
gGolden := bioGraphMaxMatchGoldenByEdmondesKarp()
120135
g := bioGraphMaxMatch(bioG, l, edmondesKarp)
121136
checkGraphOutOfOrderInString(t, g, gGolden, nil)
137+
122138
g = bioGraphMaxMatch(bioG, l, pushRelabel)
123139
gGolden = bioGraphMaxMatchGoldenByPushRelabel()
124140
checkGraphOutOfOrderInString(t, g, gGolden, nil)
141+
142+
g = bioGraphMaxMatch(bioG, l, relabelToFront)
143+
gGolden = bioGraphMaxMatchGoldenByRelabelToFront()
144+
checkGraphOutOfOrderInString(t, g, gGolden, nil)
125145
}

0 commit comments

Comments
 (0)