/// <summary> /// Compute all simple cycles up to given <paramref name="maxCycleSize"/> in the provided /// <paramref name="graph"/>. In some graphs the topology makes it impracticable to /// compute all the simple. To avoid running forever on these molecules the /// <paramref name="maxDegree"/> provides an escape clause. The value doesn't quantify /// how many cycles we get. /// </summary> /// <remarks> /// The percentage of molecules in PubChem Compound /// (Dec '12) which would successfully complete for a given Degree are listed /// below. /// <list type="table"> /// <listheader>Table 1. Number of structures processable in PubChem Compound (Dec 2012) as a result of /// setting the max degree</listheader> /// <item><term>Percent</term><term>Max Degree</term></item> /// <item><term>99%</term><term>9</term></item> <item><term>99.95%</term><term>72</term></item> /// <item><term>99.96%</term><term>84</term></item> <item><term>99.97%</term><term>126</term></item> /// <item><term>99.98%</term><term>216</term></item> <item><term>99.99%</term><term>684</term></item> /// </list> /// </remarks> /// <param name="graph">adjacency list representation of a graph</param> /// <param name="maxCycleSize">the maximum cycle size to perceive</param> /// <param name="maxDegree">escape clause to stop the algorithm running forever</param> public AllCycles(int[][] graph, int maxCycleSize, int maxDegree) { // get the order in which we remove vertices, the rank tells us // the index in the ordered array of each vertex int[] rank = GetRank(graph); int[] vertices = GetVerticesInOrder(rank); PathGraph pGraph; if (graph.Length < 64) { pGraph = new RegularPathGraph(graph, rank, maxCycleSize); } else { pGraph = new JumboPathGraph(graph, rank, maxCycleSize); } // perceive the cycles by removing the vertices in order int removed = 0; foreach (int v in vertices) { if (pGraph.Degree(v) > maxDegree) { break; // or could throw exception... } pGraph.Remove(v, cycles); removed++; } completed = removed == graph.Length; }
public virtual void K8() { int ord = 8; int[][] k8 = CompleteGraphOfSize(ord); var pg = new RegularPathGraph(k8, Identity(8), ord); List <int[]> cycles = new List <int[]>(); for (int v = 0; v < ord; v++) { pg.Remove(v, cycles); } Assert.AreEqual(8018, cycles.Count); }
public virtual void K3Degree() { int ord = 3; int[][] k3 = CompleteGraphOfSize(ord); var pg = new RegularPathGraph(k3, Identity(3), ord); // note - vertices are only added to either vertex (lowest rank) Assert.AreEqual(2, pg.Degree(0)); Assert.AreEqual(1, pg.Degree(1)); Assert.AreEqual(0, pg.Degree(2)); pg.Remove(0, new List <int[]>(0)); Assert.AreEqual(0, pg.Degree(0)); Assert.AreEqual(2, pg.Degree(1)); Assert.AreEqual(0, pg.Degree(2)); pg.Remove(1, new List <int[]>(0)); Assert.AreEqual(0, pg.Degree(0)); Assert.AreEqual(0, pg.Degree(1)); Assert.AreEqual(0, pg.Degree(2)); }
public virtual void RepeatRemoval() { int ord = 3; int[][] k3 = CompleteGraphOfSize(ord); var pg = new RegularPathGraph(k3, Identity(3), ord); List <int[]> cycles = new List <int[]>(); pg.Remove(0, cycles); Assert.AreEqual(0, cycles.Count); pg.Remove(0, cycles); Assert.AreEqual(0, cycles.Count); pg.Remove(1, cycles); Assert.AreEqual(1, cycles.Count); pg.Remove(1, cycles); Assert.AreEqual(1, cycles.Count); pg.Remove(2, cycles); Assert.AreEqual(1, cycles.Count); pg.Remove(2, cycles); Assert.AreEqual(1, cycles.Count); }