/// <summary> /// Builds the initial extension set. This is the /// set of node that may be used as seed for the /// RGraph parsing. This set depends on the constrains /// defined by the user. /// </summary> /// <param name="c1">constraint in the graph G1</param> /// <param name="c2">constraint in the graph G2</param> /// <returns>the new extension set</returns> private BitArray BuildB(BitArray c1, BitArray c2) { this.c1 = c1; this.c2 = c2; BitArray bs = new BitArray(graph.Count); // only nodes that fulfill the initial constrains // are allowed in the initial extension set : B foreach (var rn in graph) { if ((c1[rn.RMap.Id1] || BitArrays.IsEmpty(c1)) && (c2[rn.RMap.Id2] || BitArrays.IsEmpty(c2))) { bs.Set(graph.IndexOf(rn), true); } } return(bs); }
/// <summary> /// Test if set sourceBitSet is contained in set targetBitSet. /// </summary> /// <param name="sourceBitSet">a bitSet</param> /// <param name="targetBitSet">a bitSet</param> /// <returns>true if sourceBitSet is contained in targetBitSet</returns> private static bool IsContainedIn(BitArray sourceBitSet, BitArray targetBitSet) { bool result = false; if (BitArrays.IsEmpty(sourceBitSet)) { return(true); } BitArray setA = (BitArray)sourceBitSet.Clone(); setA.And(targetBitSet); if (BitArrays.Equals(setA, sourceBitSet)) { result = true; } return(result); }
/// <summary> /// Test if set A is contained in set B. /// </summary> /// <param name="A">a bitSet</param> /// <param name="B">a bitSet</param> /// <returns>true if A is contained in B</returns> private static bool IsContainedIn(BitArray A, BitArray B) { bool result = false; if (BitArrays.IsEmpty(A)) { return(true); } BitArray setA = (BitArray)A.Clone(); setA.And(B); if (BitArrays.Equals(setA, A)) { result = true; } return(result); }
/// <summary> /// Builds the initial extension set. This is the /// set of node that may be used as seed for the /// CDKRGraph parsing. This set depends on the constrains /// defined by the user. /// </summary> /// <param name="sourceBitSet">constraint in the graph G1</param> /// <param name="targetBitSet">constraint in the graph G2</param> /// <returns></returns> private BitArray BuildB(BitArray sourceBitSet, BitArray targetBitSet) { this.SourceBitSet = sourceBitSet; this.TargetBitSet = targetBitSet; BitArray bistSet = new BitArray(Graph.Count); // only nodes that fulfill the initial constrains // are allowed in the initial extension set : targetBitSet foreach (var rNode in Graph) { CheckTimeOut(); if ((sourceBitSet[rNode.RMap.Id1] || BitArrays.IsEmpty(sourceBitSet)) && (targetBitSet[rNode.RMap.Id2] || BitArrays.IsEmpty(targetBitSet))) { bistSet.Set(Graph.IndexOf(rNode), true); } } return(bistSet); }
/// <summary> /// Parsing of the CDKRGraph. This is the recursive method /// to perform a query. The method will recursively /// parse the CDKRGraph thru connected nodes and visiting the /// CDKRGraph using allowed adjacency relationship. /// </summary> /// <param name="traversed">node already parsed</param> /// <param name="extension">possible extension node (allowed neighbors)</param> /// <param name="forbidden">node forbidden (set of node incompatible with the current solution)</param> private void ParseRec(BitArray traversed, BitArray extension, BitArray forbidden) { BitArray newTraversed = null; BitArray newExtension = null; BitArray newForbidden = null; BitArray potentialNode = null; CheckTimeOut(); // if there is no more extension possible we // have reached a potential new solution if (BitArrays.IsEmpty(extension)) { Solution(traversed); } // carry on with each possible extension else { // calculates the set of nodes that may still // be reached at this stage (not forbidden) potentialNode = ((BitArray)GraphBitSet.Clone()); BitArrays.AndNot(potentialNode, forbidden); potentialNode.Or(traversed); // checks if we must continue the search // according to the potential node set if (MustContinue(potentialNode)) { // carry on research and update iteration count NbIteration = NbIteration + 1; // for each node in the set of possible extension (neighbors of // the current partial solution, include the node to the solution // and parse recursively the CDKRGraph with the new context. for (int x = BitArrays.NextSetBit(extension, 0); x >= 0; x = BitArrays.NextSetBit(extension, x + 1)) { #if !DEBUG && !TEST if (IsStop) { break; } #endif // evaluates the new set of forbidden nodes // by including the nodes not compatible with the // newly accepted node. newForbidden = (BitArray)forbidden.Clone(); newForbidden.Or((Graph[x]).Forbidden); // if maxIterator is the first time we are here then // traversed is empty and we initialize the set of // possible extensions to the extension of the first // accepted node in the solution. if (BitArrays.IsEmpty(traversed)) { newExtension = (BitArray)((Graph[x]).Extension.Clone()); } // else we simply update the set of solution by // including the neighbors of the newly accepted node else { newExtension = (BitArray)extension.Clone(); newExtension.Or((Graph[x]).Extension); } // extension my not contain forbidden nodes BitArrays.AndNot(newExtension, newForbidden); // create the new set of traversed node // (update current partial solution) // and add x to the set of forbidden node // (a node may only appear once in a solution) newTraversed = (BitArray)traversed.Clone(); newTraversed.Set(x, true); forbidden.Set(x, true); // parse recursively the CDKRGraph ParseRec(newTraversed, newExtension, newForbidden); } } } }
/// <summary> /// Assign an arbitrary matching that covers the subset of vertices. /// </summary> /// <param name="graph">adjacency list representation of graph</param> /// <param name="subset">subset of vertices in the graph</param> /// <returns>the matching was perfect</returns> internal bool ArbitaryMatching(int[][] graph, BitArray subset) { BitArray unmatched = new BitArray(subset.Length); // indicates the deg of each vertex in unmatched subset int[] deg = new int[graph.Length]; // queue/stack of vertices with deg1 vertices int[] deg1 = new int[graph.Length]; int nd1 = 0, nMatched = 0; for (int v = BitArrays.NextSetBit(subset, 0); v >= 0; v = BitArrays.NextSetBit(subset, v + 1)) { if (Matched(v)) { Trace.Assert(subset[Other(v)]); nMatched++; continue; } unmatched.Set(v, true); foreach (var w in graph[v]) { if (subset[w] && Unmatched(w)) { deg[v]++; } } if (deg[v] == 1) { deg1[nd1++] = v; } } while (!BitArrays.IsEmpty(unmatched)) { int v = -1; // attempt to select a vertex with degree = 1 (in matched set) while (nd1 > 0) { v = deg1[--nd1]; if (unmatched[v]) { break; } } // no unmatched degree 1 vertex, select the first unmatched if (v < 0 || unmatched[v]) { v = BitArrays.NextSetBit(unmatched, 0); } unmatched.Set(v, false); // find a unmatched edge and match it, adjacent degrees are updated foreach (var w in graph[v]) { if (unmatched[w]) { Match(v, w); nMatched += 2; unmatched.Set(w, false); // update neighbors of w and v (if needed) foreach (var u in graph[w]) { if (--deg[u] == 1 && unmatched[u]) { deg1[nd1++] = u; } } // if deg == 1, w is the only neighbor if (deg[v] > 1) { foreach (var u in graph[v]) { if (--deg[u] == 1 && unmatched[u]) { deg1[nd1++] = u; } } } break; } } } return(nMatched == BitArrays.Cardinality(subset)); }
/// <summary> /// Check whether the row which was added at index <paramref name="j"/> has been /// eliminated. <see cref="Eliminate()"/> should be invoked first. /// </summary> /// <param name="j">row index</param> /// <returns>whether the row was eliminated</returns> /// <seealso cref="Eliminate()"/> public bool Eliminated(int j) { return(BitArrays.IsEmpty(Row(j))); }