Beispiel #1
0
        public static UndirectedGraph Generate(int verticesCount, double edgePercent)
        {
            var graph         = new UndirectedGraph(verticesCount);
            int maxEdgesCount = verticesCount * (verticesCount - 1) / 2;
            int edgesCount    = (int)(edgePercent * maxEdgesCount);
            var edgesIndexes  = GenerateRandomNumbersWithoutRepeating(edgesCount, maxEdgesCount);

            for (int i = 0, edgeIterator = 0; i < verticesCount; i++)
            {
                for (int j = i + 1; j < verticesCount; j++, edgeIterator++)
                {
                    if (edgesIndexes.Contains(edgeIterator))
                    {
                        graph.AddEdge(i, j);
                    }
                }
            }
            return(graph);
        }
Beispiel #2
0
        public static UndirectedGraph Load(string filename)
        {
            string[] readTexts = File.ReadAllText(filename).TrimEnd('\n').Split('\n');
            if (readTexts.Length != int.Parse(readTexts[1]) + 2)
            {
                throw new Exception("Bad graph format - edge count incorrect");
            }
            int verticeCount = int.Parse(readTexts[0]);
            var graph        = new UndirectedGraph(verticeCount);

            for (int i = 2; i < readTexts.Length; i++)
            {
                string[] vertices = readTexts[i].Split(' ');
                if (vertices.Length != 2)
                {
                    throw new Exception("Bad graph format - too many vertices in line " + i.ToString());
                }
                graph.AdjacencyMatrix[int.Parse(vertices[0]) - 1, int.Parse(vertices[1]) - 1] = 1;
                graph.AdjacencyMatrix[int.Parse(vertices[1]) - 1, int.Parse(vertices[0]) - 1] = 1;
            }
            return(graph);
        }
Beispiel #3
0
        private UndirectedGraph ColorGraphRecursion(UndirectedGraph graph)
        {
            if (graph.NotColoredEdges.Count == 0)
            {
                return(graph);
            }

            var graphForMatching = new UndirectedGraph(graph);

            graphForMatching.Edges = graphForMatching.NotColoredEdges;
            var matchings = GetGraphMatchings(graphForMatching);

            foreach (var matching in matchings)
            {
                var  graphPrim      = new UndirectedGraph(graph);
                bool anyEdgeColored = false;
                foreach (var edge in matching)
                {
                    var color = graphPrim.CalculateColor(edge);
                    if (color != null)
                    {
                        graphPrim.ColorEdge(new Edge(edge.V1, edge.V2, color.Value));
                        anyEdgeColored = true;
                    }
                    else
                    {
                        anyEdgeColored = false;
                        break;
                    }
                }
                if (anyEdgeColored)
                {
                    return(ColorGraphRecursion(graphPrim));
                }
            }

            return(null);
        }
Beispiel #4
0
 public UndirectedGraph ColorGraph(UndirectedGraph graph)
 {
     graph.InitializeNotUsedColors();
     return(ColorGraphRecursion(graph));
 }
Beispiel #5
0
 private List <Edge> GetPathFromRoot(UndirectedGraph undirectedGraph, int root, int targetV)
 {
     return(GetPathToRoot(undirectedGraph, targetV, root));
 }
Beispiel #6
0
 public Blossom(UndirectedGraph graph)
 {
     _graph      = new UndirectedGraph(graph);
     _graphEdges = _graph.Edges;
 }
Beispiel #7
0
        private List <Edge> Lift(List <Edge> path, List <Edge> blossom, int blossomRoot, UndirectedGraph graph, List <Edge> currentMatching)
        {
            if (path.Count == 0)
            {
                return(path);
            }
            List <Edge> blossomPart      = null;
            List <Edge> rootNeighbours   = path.Where(e => e.V1 == blossomRoot || e.V2 == blossomRoot).ToList();
            int         blossomEdgeIndex = path.IndexOf(path.First(e => e.V1 == blossomRoot || e.V2 == blossomRoot));

            if (rootNeighbours.Count == 1)
            {
                List <Edge> unrolledBlossom = UnrollFromRoot(blossom, blossomRoot);
                if (blossomEdgeIndex == 0)
                {
                    int neighbourIndex  = rootNeighbours[0].V1 == blossomRoot ? rootNeighbours[0].V2 : rootNeighbours[0].V1;
                    int realBlossomRoot = unrolledBlossom.SelectMany(e => new List <int> {
                        e.V1, e.V2
                    }).Distinct().First(v => graph[v, neighbourIndex] == 1);
                    List <Edge> realUnrolledBlossom = UnrollFromRoot(blossom, realBlossomRoot);
                    if (currentMatching.Contains(realUnrolledBlossom[realUnrolledBlossom.Count - 1], new EdgeComparer()))
                    {
                        realUnrolledBlossom.Reverse();
                    }
                    return(realUnrolledBlossom.Take(blossom.Count - 1).Reverse().
                           Concat(new List <Edge>()
                    {
                        new Edge(realBlossomRoot, neighbourIndex)
                    }).Concat(path.Skip(1)).ToList());
                }
                else
                {
                    return(path.Concat(unrolledBlossom.Take(blossom.Count - 1)).ToList());
                }
            }
            else
            {
                if (rootNeighbours.Count != 2)
                {
                    throw new Exception("Invalid neighbours number");
                }

                int liftedRootNeighbour = rootNeighbours.SelectMany(e => new List <int> {
                    e.V1, e.V2
                }).Distinct().First(v => v != blossomRoot && graph[v, blossomRoot] == 1);
                int liftedNonRootNeighbour = rootNeighbours.SelectMany(e => new List <int> {
                    e.V1, e.V2
                }).Distinct().First(v => v != blossomRoot && v != liftedRootNeighbour);

                List <Edge> unrolledBlossom = UnrollFromRoot(blossom, blossomRoot);

                int blossomNeighbour = unrolledBlossom.SelectMany(e => new List <int> {
                    e.V1, e.V2
                }).Distinct().First(v => v != blossomRoot && graph[v, liftedNonRootNeighbour] == 1);
                Edge neighbourBlossomEdge = unrolledBlossom.First(e => e.V1 == blossomNeighbour || e.V2 == blossomNeighbour);

                int distanceV = RootDistance(unrolledBlossom, neighbourBlossomEdge);
                if (distanceV % 2 == 0)
                {
                    blossomPart = unrolledBlossom.Take(distanceV).ToList();
                }
                else
                {
                    blossomPart = unrolledBlossom.Skip(distanceV).Reverse().ToList();
                }

                return(path.Take(blossomEdgeIndex).
                       Concat(new List <Edge> {
                    new Edge(liftedRootNeighbour, blossomRoot)
                }).
                       Concat(blossomPart).
                       Concat(new List <Edge> {
                    new Edge(blossomNeighbour, liftedNonRootNeighbour)
                }).
                       Concat(path.Skip(blossomEdgeIndex + 2)).ToList());
            }
        }