/// <summary> Construct the edge short cycles for the /// given initial cycles. </summary> public EdgeShortCycles(InitialCycles initialCycles) { int[][] graph = initialCycles.Graph; int[] sizeOf = new int[initialCycles.GetNumberOfEdges()]; this.paths = new List <int[]>(initialCycles.GetNumberOfCycles()); // cycles are returned ordered by length foreach (var cycle in initialCycles.GetCycles()) { int length = cycle.Length; int[] path = cycle.Path; bool found = false; // check if any vertex is the shortest through a vertex in the path for (int i = 1; i < path.Length; i++) { int idx = initialCycles.IndexOfEdge(path[i - 1], path[i]); if (sizeOf[idx] < 1 || length <= sizeOf[idx]) { found = true; sizeOf[idx] = length; } } if (found) { foreach (var p in cycle.GetFamily()) { paths.Add(p); } } } }
/// <summary> /// Generate the minimum cycle basis from a precomputed set of initial /// cycles. This constructor allows on to specify that the graph is /// connected which allows an optimisation to be used. /// </summary> /// <param name="initial">set of initial cycles.</param> /// <param name="connected">the graph is known to be connected</param> /// <exception cref="System.ArgumentNullException">null InitialCycles provided</exception> internal MinimumCycleBasis(InitialCycles initial, bool connected) { CheckNotNull(initial, nameof(initial), "No InitialCycles provided"); this.graph = initial.Graph; this.basis = new GreedyBasis(initial.GetNumberOfCycles(), initial.GetNumberOfEdges()); // a undirected unweighted connected graph there are |E| - (|V| + 1) // cycles in the minimum basis int lim = connected ? initial.GetNumberOfEdges() - graph.Length + 1 : int.MaxValue; // processing by size add cycles which are independent of smaller cycles foreach (var cycle in initial.GetCycles()) { if (basis.Count < lim && basis.IsIndependent(cycle)) { basis.Add(cycle); } } }
/// <summary> /// Generate the relevant cycle basis from a precomputed set of initial /// cycles. /// </summary> /// <param name="initial">set of initial cycles.</param> /// <exception cref="System.ArgumentNullException">null InitialCycles provided</exception> internal RelevantCycles(InitialCycles initial) { CheckNotNull(initial, nameof(initial), "No InitialCycles provided"); this.basis = new GreedyBasis(initial.GetNumberOfCycles(), initial.GetNumberOfEdges()); // processing by size add cycles which are independent of smaller cycles foreach (var length in initial.Lengths) { basis.AddAll(Independent(initial.GetCyclesOfLength(length))); } }
/// <summary> /// Determine the essential cycles from a precomputed set of initial cycles /// and relevant cycles. /// </summary> /// <param name="relevant"></param> /// <param name="initial">a molecule graph</param> internal EssentialCycles(RelevantCycles relevant, InitialCycles initial) { CheckNotNull(relevant, nameof(relevant), "No RelevantCycles provided"); this.initial = CheckNotNull(initial, nameof(initial), "No InitialCycles provided"); this.basis = new GreedyBasis(initial.GetNumberOfCycles(), initial.GetNumberOfEdges()); this.essential = new List <Cycle>(); // for each cycle added to the basis, if it can be // replaced with one of equal size it is non-essential foreach (var cycles in GroupByLength(relevant)) { foreach (var c in GetMembersOfBasis(cycles)) { if (IsEssential(c, cycles)) { essential.Add(c); } } } }