2

クリークの問題を解決しようとしています。私は Bron Kerbosch Clique アルゴリズムを使用しています。これは Java で適切に記述されており、巧妙な実装がここにあります。ただし、クリーク硬度のおかげで、非常に遅くなる可能性があり、

私がやりたいことは、それらが接続されていることがわかっている頂点の初期セットを使用することです。次にメソッドを呼び出します。私の人生では、結果が派閥ではないということで、ここで何が間違っているのかわかりません。

注: コメント付きのコードは、元のコード (上記のリンク) からのものです。

public class BronKerboschCliqueFinder<V, E> {

    //~ Instance fields --------------------------------------------------------

private final UndirectedGraph<V, E> graph;
private Collection<Set<V>> cliques;

 //   public Collection<Set<V>> getAllMaximalCliques()
 public Collection<Set<V>> getAllMaximalCliqes(Set<String> initials){
{
    // TODO:  assert that graph is simple

    cliques = new ArrayList<Set<V>>();
    List<V> potential_clique = new ArrayList<V>();
    List<V> candidates = new ArrayList<V>();
    List<V> already_found = new ArrayList<V>();
   // candidates.addAll(graph.getVertices());  instead I do this:
    for(V v : graph.getVertices()){
        if(initial.contains(v)){
            potential_clique.add(v);
        }else{
            candidates.add(v);
        }
    }
    findCliques(potential_clique, candidates, already_found);
    return cliques;
}


private void findCliques(
    List<V> potential_clique,
    List<V> candidates,
    List<V> already_found)
{

    List<V> candidates_array = new ArrayList<V>(candidates);
    if (!end(candidates, already_found)) {
        // for each candidate_node in candidates do
        for (V candidate : candidates_array) {
            List<V> new_candidates = new ArrayList<V>();
            List<V> new_already_found = new ArrayList<V>();

            // move candidate node to potential_clique
            potential_clique.add(candidate);
            candidates.remove(candidate);

            // create new_candidates by removing nodes in candidates not
            // connected to candidate node
            for (V new_candidate : candidates) {
                if (graph.isNeighbor(candidate, new_candidate))
                {
                    new_candidates.add(new_candidate);
                } // of if
            } // of for

            // create new_already_found by removing nodes in already_found
            // not connected to candidate node
            for (V new_found : already_found) {
                if (graph.isNeighbor(candidate, new_found)) {
                    new_already_found.add(new_found);
                } // of if
            } // of for

            // if new_candidates and new_already_found are empty
            if (new_candidates.isEmpty() && new_already_found.isEmpty()) {
                // potential_clique is maximal_clique
                cliques.add(new HashSet<V>(potential_clique));
                return;
            } // of if
            else {
                // recursive call
                findCliques(
                    potential_clique,
                    new_candidates,
                    new_already_found);
            } // of else

            // move candidate_node from potential_clique to already_found;
            already_found.add(candidate);
            potential_clique.remove(candidate);
        } // of for
    } // of if
}

private boolean end(List<V> candidates, List<V> already_found)
{
    // if a node in already_found is connected to all nodes in candidates
    boolean end = false;
    int edgecounter;
    for (V found : already_found) {
        edgecounter = 0;
        for (V candidate : candidates) {
            if (graph.isNeighbor(found, candidate)) {
                edgecounter++;
            } // of if
        } // of for
        if (edgecounter == candidates.size()) {
            end = true;
        }
    } // of for
    return end;
}
}

要するに、私の唯一の変更はgetAllMaximalCliques方法です。ここで再帰呼び出しメソッドがどのように機能するかはよくわかりません。

何か助けや指示をいただければ幸いです。

4

1 に答える 1