/// <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)); }