/// <summary> /// Находит все минимальные гамаки в графе /// </summary> /// <returns>Возвращает множество гамаков для каждой вершины</returns> /// <param name="gi">Граф</param> public static List<SortedSet<int>> GetAllHammocks(GraphInfo gi) { var gp = gi.Gr; var tgp = TransposeGraph(gp); var dp1 = CalcDynamicOnGraph(gp, gi.EndVertex); var dp2 = CalcDynamicOnGraph(tgp, gi.StartVertex); // Оставляем только нужные вершины (переходы) if (gi.Include != null) { for (int i = 0; i < gp.Count; i++) { if (!gi.Include.Contains(i)) { dp1[i].Clear(); dp2[i].Clear(); } } } // Удаляем гамаки между позициями (оставляем между переходами) for (int i = 0; i < gp.Count; i++) { dp1[i].Remove(i); var newSet = new SortedSet<int>(); foreach (int v in dp1[i]) if (dp2[v].Contains(i)) newSet.Add(v); dp1[i] = newSet; } // Оставляем минимальные гамаки // Гамак является минимальным, если его нельзя разбить на два гамака for (int v = 0; v < dp1.Count; v++) dp1[v].RemoveWhere(x => IsBadHammock(dp1, v, x)); return dp1; }
/// <summary> /// Находит гамак, начинающийся в данной вершине максимального размера меньше заданного. /// Это есть ребенок данного гамака /// </summary> /// <returns>Гамак</returns> /// <param name="gi">Граф</param> /// <param name="v">Номер вершины</param> /// <param name="size">Размер текущего гамака</param> protected virtual HammockTree GetChildren(GraphInfo gi, int v, int size) { var ans = new HammockTree(); foreach (var node in gi.HammocksStartedAtVertex[v]) if (gi.ListOfHammocks[node].Size > ans.Size && gi.ListOfHammocks[node].Size < size) ans = gi.ListOfHammocks[node]; return ans; }
/// <summary> /// Строит дерево гамаков по данному графу /// </summary> /// <returns>Возвращает указатель на корень дерева</returns> /// <param name="gi">Граф</param> public static HammockTree CreateHammockTree(GraphInfo gi) { var root = new HammockTree(); foreach (var node in gi.ListOfHammocks) if (node.Size > root.Size) root = node; root.FindChildren(gi); return root; }
/// <summary> /// Ищем всех потомков данной вершины в дереве гамаков /// (то есть все гамаки, которые содержит этот гамак) /// </summary> /// <param name="gi">Граф</param> protected virtual void FindChildren(GraphInfo gi) { var used = new SortedSet<int>(); var q = new Queue<int>(); q.Enqueue(Start); used.Add(Start); while (q.Count > 0) { int cur = q.Dequeue(); if (cur == End) continue; if (gi.HammocksStartedAtVertex[cur].Count > 0) { var next = GetChildren(gi, cur, Size); if (next.Size > 0) { if (!used.Contains(next.End)) { used.Add(next.End); q.Enqueue(next.End); } Childs.Add(next); next.Parent = this; next.FindChildren(gi); continue; } } foreach (int next in gi.Gr[cur]) { if (!used.Contains(next)) { used.Add(next); q.Enqueue(next); } } } foreach (var child in Childs) child.FindSiblings(); }