3 import . "github.com/onsi/gomega/matchers/support/goraph/node"
4 import . "github.com/onsi/gomega/matchers/support/goraph/edge"
5 import "github.com/onsi/gomega/matchers/support/goraph/util"
7 func (bg *BipartiteGraph) LargestMatching() (matching EdgeSet) {
8 paths := bg.maximalDisjointSLAPCollection(matching)
11 for _, path := range paths {
12 matching = matching.SymmetricDifference(path)
14 paths = bg.maximalDisjointSLAPCollection(matching)
20 func (bg *BipartiteGraph) maximalDisjointSLAPCollection(matching EdgeSet) (result []EdgeSet) {
21 guideLayers := bg.createSLAPGuideLayers(matching)
22 if len(guideLayers) == 0 {
26 used := make(map[Node]bool)
28 for _, u := range guideLayers[len(guideLayers)-1] {
29 slap, found := bg.findDisjointSLAP(u, matching, guideLayers, used)
31 for _, edge := range slap {
32 used[edge.Node1] = true
33 used[edge.Node2] = true
35 result = append(result, slap)
42 func (bg *BipartiteGraph) findDisjointSLAP(
45 guideLayers []NodeOrderedSet,
48 return bg.findDisjointSLAPHelper(start, EdgeSet{}, len(guideLayers)-1, matching, guideLayers, used)
51 func (bg *BipartiteGraph) findDisjointSLAPHelper(
56 guideLayers []NodeOrderedSet,
59 used[currentNode] = true
61 if currentLevel == 0 {
62 return currentSLAP, true
65 for _, nextNode := range guideLayers[currentLevel-1] {
70 edge, found := bg.Edges.FindByNodes(currentNode, nextNode)
75 if matching.Contains(edge) == util.Odd(currentLevel) {
79 currentSLAP = append(currentSLAP, edge)
80 slap, found := bg.findDisjointSLAPHelper(nextNode, currentSLAP, currentLevel-1, matching, guideLayers, used)
84 currentSLAP = currentSLAP[:len(currentSLAP)-1]
87 used[currentNode] = false
91 func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers []NodeOrderedSet) {
92 used := make(map[Node]bool)
93 currentLayer := NodeOrderedSet{}
95 for _, node := range bg.Left {
96 if matching.Free(node) {
98 currentLayer = append(currentLayer, node)
102 if len(currentLayer) == 0 {
103 return []NodeOrderedSet{}
105 guideLayers = append(guideLayers, currentLayer)
111 lastLayer := currentLayer
112 currentLayer = NodeOrderedSet{}
114 if util.Odd(len(guideLayers)) {
115 for _, leftNode := range lastLayer {
116 for _, rightNode := range bg.Right {
121 edge, found := bg.Edges.FindByNodes(leftNode, rightNode)
122 if !found || matching.Contains(edge) {
126 currentLayer = append(currentLayer, rightNode)
127 used[rightNode] = true
129 if matching.Free(rightNode) {
135 for _, rightNode := range lastLayer {
136 for _, leftNode := range bg.Left {
141 edge, found := bg.Edges.FindByNodes(leftNode, rightNode)
142 if !found || !matching.Contains(edge) {
146 currentLayer = append(currentLayer, leftNode)
147 used[leftNode] = true
153 if len(currentLayer) == 0 {
154 return []NodeOrderedSet{}
156 guideLayers = append(guideLayers, currentLayer)