/// <summary>
        /// Fügt dem Graphen eine weitere Kante hinzu.
        /// </summary>
        /// <param name="edge"></param>
        public void AddEdge(HyperEdge edge)
        {
            if (this.Edges.Contains(edge))
            {
                throw new ArgumentException("Diese Kante existiert bereits im Graphen.");
            }

            this.Edges.Add(edge);
        }
        /// <summary>
        /// Lädt einen HyperGraphen aus einer Datei.
        /// </summary>
        /// <param name="path">Der Pfad zu der Datei.</param>
        /// <returns>Den geladenen Graphen.</returns>
        public static HyperGraph LoadHyperGraphFromFile(string path)
        {
            // Die Daten aus der Datei laden.
            IEnumerable <string> lines = File.ReadLines(path);

            if (lines.Count() < 1)
            {
                throw new InvalidDataException("The given File is empty");
            }

            // Den Graphen erstellen.
            HyperGraph hyperGraph = new HyperGraph();

            // Die einzelnen Zeilen der Datei auslesen.
            int lineNumber = 0;
            IEnumerator <string> linesEnumerator = lines.GetEnumerator();

            while (linesEnumerator.MoveNext())
            {
                string[] lineData = linesEnumerator.Current.Split(' ');
                if (lineData.Count() < 2)
                {
                    continue;
                    //throw new ArgumentException("One edge must connect at least two vertices (Line: " + lineNumber + ").");
                }

                // Die Knoten hinzufügen, falls noch nicht vorhanden.
                foreach (string vertex in lineData)
                {
                    if (!hyperGraph.HasVertex(vertex))
                    {
                        hyperGraph.AddVertex(vertex);
                    }
                }

                // Die Kante hinzufügen, falls noch nicht vorhanden
                HyperEdge hyperEdge = new HyperEdge(lineData);
                if (!hyperGraph.HasEdge(hyperEdge))
                {
                    hyperGraph.AddEdge(hyperEdge);
                }

                lineNumber++;
            }

            return(hyperGraph);
        }
        /// <summary>
        /// Überschreibt die Equals Methode für diese Klasse.
        /// </summary>
        /// <param name="obj">Das Objekt mit dem verglichen werden soll.</param>
        /// <returns>True, wenn das Objekt und diese Instanz der Klasse gleich sind, false wenn nicht.</returns>
        public override bool Equals(object obj)
        {
            if (obj == null || !obj.GetType().Equals(this.GetType()))
            {
                return(false);
            }

            HyperEdge other = (HyperEdge)obj;

            if (other.VertexCount != this.VertexCount || other.IsVisited != this.IsVisited)
            {
                return(false);
            }

            for (int i = 0; i < this.VertexCount; i++)
            {
                if (!other.Vertices.Contains(this.Vertices[i]) || !this.Vertices.Contains(other.Vertices[i]))
                {
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// Werte wie Colors, Parent etc. als value, nicht referenz übergben?!
        /// Cycles als Referenz übergben.
        /// </summary>
        public void GetSimpleCycle2(
            HyperEdge u,
            HyperEdge p,
            List <Tuple <HyperEdge, string> > parent,
            Dictionary <HyperEdge, int> color,
            List <List <Tuple <HyperEdge, string> > > cycles)
        {
            // edge was completly visited before
            if (color.ContainsKey(u) && color[u] == 2)
            {
                return;
            }

            // possible cycle detected
            if (color.ContainsKey(u) && color[u] == 1)
            {
                // Ein Zyklus im Triominograph muss immer min. die Länge 6 (nur 3er Kanten) bzw. 12 (inkl. 2er Kanten haben)
                int cycleBegin = parent.Count - 12;
                if (cycleBegin >= 0)
                {
                    // Suche den Anfang des Zyklus (soweit vorhanden)
                    while (parent[cycleBegin].Item1 != u && cycleBegin > 0)
                    {
                        cycleBegin--;
                    }

                    // Wenn anfang gefunden wurde, den Zyklus speichern.
                    if (parent[cycleBegin].Item1.Equals(u))
                    {
                        List <Tuple <HyperEdge, string> > cycle = new List <Tuple <HyperEdge, string> >();
                        for (int i = cycleBegin; i < parent.Count; i++)
                        {
                            cycle.Add(parent[i]);
                        }

                        cycles.Add(cycle);
                    }
                }
            }

            if (color.ContainsKey(u))
            {
                color[u] = 1;
            }

            // Den Knoten ermitteln, über welchen die Kante u erreicht wurde.
            string parentVertex = string.Empty;

            if (parent.Count > 0)
            {
                parentVertex = parent.Last().Item2;
            }

            // die Knoten der Kante u ermitteln, die nicht dem eingehenden Knoten entsprechen (diese müssen noch besucht werden)
            IEnumerable <string> adjacentVertices = u.GetNeighborVertices(parentVertex);

            // Die Anzahl der Knoten welche die nächste Kante besitzen muss
            //ermitteln (Kanten mit 2 und 3 Knoten werden immer im Wechsel durchlaufen).
            int vCount = (u.VertexCount == 2) ? 3 : 2;

            // die weiteren Knoten der Kante u besuchen
            foreach (string vertex in adjacentVertices)
            {
                // Alle möglichen Kanten von dem aktuellen Knoten aus ermitteln.
                IEnumerable <HyperEdge> edges = this.GetAdjacentEdges(vertex, vCount);
                if (parent.Count - 2 >= 0)
                {
                    edges = edges.Where(e => !e.Equals(parent[parent.Count - 1].Item1));
                }

                foreach (HyperEdge edge in edges)
                {
                    // Parent Kante und Knoten für die nächste Kante hinzfügen.
                    // Für den nachfolgenden Knotenvergleich muss darauf geachtet werden,
                    // dass hier der Wert des Knotens der nächsten Kante verwendet wird
                    // (in diesem ist die Position des Knotens in der nächsten Kante gespeichert)
                    parent.Add(new Tuple <HyperEdge, string>(u, edge.GetVertexEdgeValue(vertex)));
                    this.GetSimpleCycle2(edge, u, parent, color, cycles);
                }
            }

            if (color.ContainsKey(u))
            {
                color[u] = 2;
            }
        }
 /// <summary>
 /// Überprüft für eine Kante, ob diese bereits im Graphen existiert.
 /// </summary>
 /// <param name="edge">Die zu überprüfende Kante.</param>
 /// <returns>True, wenn die Kante im Graphen vorhanden ist, False wenn nicht.</returns>
 public bool HasEdge(HyperEdge edge)
 {
     return(this.Edges.Contains(edge));
 }