func (bg *BipartiteGraph) findDisjointSLAPHelper( currentNode Node, currentSLAP EdgeSet, currentLevel int, matching EdgeSet, guideLayers []NodeOrderedSet, used map[Node]bool, ) (EdgeSet, bool) { used[currentNode] = true if currentLevel == 0 { return currentSLAP, true } for _, nextNode := range guideLayers[currentLevel-1] { if used[nextNode] { continue } edge, found := bg.Edges.FindByNodes(currentNode, nextNode) if !found { continue } if matching.Contains(edge) == util.Odd(currentLevel) { continue } currentSLAP = append(currentSLAP, edge) slap, found := bg.findDisjointSLAPHelper(nextNode, currentSLAP, currentLevel-1, matching, guideLayers, used) if found { return slap, true } currentSLAP = currentSLAP[:len(currentSLAP)-1] } used[currentNode] = false return nil, false }
func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers []NodeOrderedSet) { used := make(map[Node]bool) currentLayer := NodeOrderedSet{} for _, node := range bg.Left { if matching.Free(node) { used[node] = true currentLayer = append(currentLayer, node) } } if len(currentLayer) == 0 { return []NodeOrderedSet{} } else { guideLayers = append(guideLayers, currentLayer) } done := false for !done { lastLayer := currentLayer currentLayer = NodeOrderedSet{} if util.Odd(len(guideLayers)) { for _, leftNode := range lastLayer { for _, rightNode := range bg.Right { if used[rightNode] { continue } edge, found := bg.Edges.FindByNodes(leftNode, rightNode) if !found || matching.Contains(edge) { continue } currentLayer = append(currentLayer, rightNode) used[rightNode] = true if matching.Free(rightNode) { done = true } } } } else { for _, rightNode := range lastLayer { for _, leftNode := range bg.Left { if used[leftNode] { continue } edge, found := bg.Edges.FindByNodes(leftNode, rightNode) if !found || !matching.Contains(edge) { continue } currentLayer = append(currentLayer, leftNode) used[leftNode] = true } } } if len(currentLayer) == 0 { return []NodeOrderedSet{} } else { guideLayers = append(guideLayers, currentLayer) } } return }