private PartialDecomposition GetFirstComponent(PartialDecomposition decomposition) { var faces = decomposition.GetRemainingFaces(); if (Faces.Count != 0) { List <TNode> firstFace; if (preferSmallCycles) { var smallestFaceIndex = faces.MinBy(x => x.Count); firstFace = faces[smallestFaceIndex]; } else { var largestFaceIndex = faces.MaxBy(x => x.Count); firstFace = faces[largestFaceIndex]; } var cycleComponent = new GraphComponent() { Nodes = firstFace, IsFromFace = true, MinimumNeighborChainNumber = 0, }; logger.WriteLine("Starting with cycle"); logger.WriteLine(cycleComponent); return(decomposition.AddChain(cycleComponent.Nodes, true)); } var startingNode = Graph.Vertices.First(x => Graph.GetNeighbours(x).Count() == 1); var treeComponent = GetTreeComponent(decomposition, startingNode); logger.WriteLine("Starting with tree"); logger.WriteLine(treeComponent); return(decomposition.AddChain(treeComponent.Nodes, false)); }
private PartialDecomposition ExtendDecomposition(PartialDecomposition decomposition) { var remainingFace = decomposition.GetRemainingFaces(); var blacklist = new List <TNode>(); var components = new List <GraphComponent>(); foreach (var node in decomposition.GetAllCoveredVertices()) { var neighbors = Graph.GetNeighbours(node); var notCoveredNeighbors = neighbors.Where(x => !decomposition.IsCovered(x)); var treeStartingNodes = new List <TNode>(); foreach (var neighbor in notCoveredNeighbors) { if (blacklist.Contains(neighbor)) { continue; } var foundFace = false; foreach (var face in remainingFace) { if (!face.Contains(neighbor)) { continue; } var cycleComponent = GetCycleComponent(decomposition, face); components.Add(cycleComponent); blacklist.AddRange(cycleComponent.Nodes); foundFace = true; break; } if (foundFace) { continue; } treeStartingNodes.Add(neighbor); } if (treeStartingNodes.Count != 0) { if (startTreeWithMultipleVertices) { var treeComponent = GetTreeComponent(decomposition, treeStartingNodes); components.Add(treeComponent); blacklist.AddRange(treeComponent.Nodes); } else { foreach (var startingNode in treeStartingNodes) { var treeComponent = GetTreeComponent(decomposition, startingNode); components.Add(treeComponent); blacklist.AddRange(treeComponent.Nodes); } } } } logger.WriteLine(); logger.WriteLine("Extending decomposition"); logger.WriteLine("Candidates:"); foreach (var component in components) { logger.WriteLine(component); } logger.WriteLine(); var cycleComponents = components.Where(x => x.IsFromFace).ToList(); if (cycleComponents.Count != 0) { var nextCycleIndex = preferSmallCycles ? cycleComponents.MinBy(x => x.Nodes.Count) : cycleComponents.MaxBy(x => x.Nodes.Count); var nextCycle = cycleComponents[nextCycleIndex]; logger.WriteLine("Adding smallest cycle component"); logger.WriteLine(nextCycle); return(decomposition.AddChain(nextCycle.Nodes, true)); } var treeComponents = components .Where(x => !x.IsFromFace) .OrderBy(x => x.MinimumNeighborChainNumber) .ThenByDescending(x => x.Nodes.Count) .ToList(); var biggestTree = treeComponents[0]; if (mergeSmallChains) { if (biggestTree.Nodes.Count < maxTreeSize) { for (var i = 1; i < treeComponents.Count; i++) { var component = treeComponents[i]; if (component.Nodes.Count + biggestTree.Nodes.Count <= maxTreeSize) { biggestTree.Nodes.AddRange(component.Nodes); } } } } logger.WriteLine("Adding biggest oldest tree component"); logger.WriteLine(biggestTree); return(decomposition.AddChain(biggestTree.Nodes, false)); }