// This is an improved version of Algorithm 12 of the PhD thesis by Sadia Sharmin, which runs in O(n) instead of O(n^2) // The RelativeNeighborhood selection method picks the next vertex based on the ratio of neighbors that are already contained in N(Left) // While in the PhD thesis the algorithm loops over all vertices w in N(v) * right to determine if they are internal/external, we can make this faster // by realizing that |((N(v) * right) \ (N(left) * right)| is already equal to the size of the external set. This is also equal to the symmetric difference. private static int RelativeNeighborhood(Graph graph, BitSet left, BitSet right) { // Minimum ratio found so far double minRatio = double.MaxValue; // Vertex that we will choose int chosen = -1; // Set of vertices in right that are adjacent to vertices in left BitSet nl = graph.Neighborhood(left) * right; Dictionary<int, double> ratios = new Dictionary<int, double>(); foreach (int v in nl) { // Neighborhood of v BitSet nv = graph.OpenNeighborhood(v) * right; // Number of vertices outside of N(left) * right, but inside N(v) * right double external_v = (nv - nl).Count; // Number of vertices inside of both N(left) * right and N(v) * right double internal_v = nv.Count - external_v; if (internal_v == 0) internal_v = 1; // cant devide by zero! // Possibly update the minimum ratio found so far double ratio = external_v / internal_v; ratios[v+1] = ratio; if (ratio < minRatio) { chosen = v; minRatio = ratio; } } return chosen; }
/*************************/ // Candidate strategy /*************************/ public static BitSet Candidates(Graph graph, BitSet left, BitSet right, CandidateStrategy candidateStrategy) { BitSet nl = graph.Neighborhood(left) * right; return candidateStrategy == CandidateStrategy.All ? right.Copy() : (nl + graph.Neighborhood(nl)) * right; }
/*************************/ // Selection algorithms for the next vertex in the sequence /*************************/ // Implementation of Algorithm 11 of the PhD thesis by Sadia Sharmin // The LeastUncommonNeighbor selection method finds the vertex in right that has the fewest neighbors in right that are // not adjacent to a vertex in left. In other words, we add as few as possibly new vertices to the neighborhoods. private static int LeastUncommonNeighbor(Graph graph, BitSet left, BitSet right) { // Minimum symmetric difference found so far int minSymmDiff = int.MaxValue; // Vertex that we will choose int chosen = -1; // Set of vertices in right that are adjacent to vertices in left BitSet nl = graph.Neighborhood(left) * right; foreach (int v in right) { // Neighborhood of v in right BitSet nv = graph.OpenNeighborhood(v) * right; // Count the difference between N(v) and N(Left) int symmDiff = (nv - nl).Count; // Possibly update the best choice so far if (symmDiff < minSymmDiff) { minSymmDiff = symmDiff; chosen = v; } } return chosen; }