/// <summary> /// Create a new cyclic vertex search for the provided graph. /// </summary> /// <param name="graph">adjacency list representation of a graph</param> internal RegularCyclicVertexSearch(IReadOnlyList <IReadOnlyList <int> > graph) { this.g = graph; int n = graph.Count; // skip search if empty graph if (n == 0) { return; } state = new long[n]; // start from vertex 0 Search(0, 0L, 0L); // if disconnected we have not visited all vertices int v = 1; while (Longs.BitCount(visited) != n) { // haven't visited v, start a new search from there if (!Visited(v)) { Search(v, 0L, 0L); } v++; } // no longer needed for the lifetime of the object state = null; }
/// <summary> /// Find the next index that the <i>cycle</i> intersects with by at least two /// vertices. If the intersect of a vertex set with another contains more /// then two vertices it cannot be edge disjoint. /// </summary> /// <param name="start">start searching from here</param> /// <param name="cycle">test whether any current cycles are fused with this one</param> /// <returns>the index of the first fused after 'start', -1 if none</returns> private int IndexOfFused(int start, long cycle) { for (int i = start; i < cycles.Count(); i++) { long intersect = cycles[i] & cycle; if (intersect != 0 && Longs.BitCount(intersect) > 1) { return(i); } } return(-1); }
/// <summary> /// Convert the bits of a <see cref="long"/> to an array of integers. The size of /// the output array is the number of bits set in the value. /// </summary> /// <param name="set">value to convert</param> /// <returns>array of the set bits in the long value</returns> internal static int[] ToArray(long set) { int[] vertices = new int[Longs.BitCount(set)]; int i = 0; // fill the cyclic vertices with the bits that have been set for (int v = 0; i < vertices.Length; v++) { if (IsBitSet(set, v)) { vertices[i++] = v; } } return(vertices); }
/// <summary> /// Add the cycle vertices to our discovered cycles. The cycle is first /// checked to see if it is isolated (shares at most one vertex) or /// <i>potentially</i> fused. /// </summary> /// <param name="cycle">newly discovered cyclic vertex set</param> private void Add(long cycle) { long intersect = cyclic & cycle; // intersect by more then 1 vertex, we 'may' have a fused cycle if (intersect != 0 && Longs.BitCount(intersect) > 1) { AddFused(cycle); } else { AddIsolated(cycle); } cyclic |= cycle; }