将等效图合并在一起

时间:2012-12-03 00:04:49

标签: java algorithm data-structures hash graph

我无法理解如何将两个图形合并在一起。见下图: enter image description here

这里我想将两个图形与根合并为A和E.由于E较小,我希望它指向较大图形A的根。我有一个名为compressToRoot()的函数一个参数,它使自身和根点之间的每个节点指向自指参根(因此,对于compressToRoot(D):D-> A,C-> A,B-> A)。如果我有这个功能,

public Equivalence<E> mergeClassesContaining(E a, E b);

如果它们不属于同一等价类,我需要先compressToRoot(a)compressToRoot(b) - 例如,D和F不同,但C和D是相同的。然后,我取较小的一个(右边,E-F)并将其根与左边较大的根合并,得到一个在右边。然后,我更新左侧的大小,并从确定大小rootSizeMap的地图中删除右侧的根。我有两个类实例变量,rootSizeMapparentMap如下所示:

 private Map<E,E>       parentMap   = new HashMap<E,E>();  //maps node to parent
 private Map<E,Integer> rootSizeMap = new HashMap<E,Integer>(); //maps node to size of class

如何完成mergeClassesContaining(E a, E b)函数,以便确定哪个是较小的图形并将其根指向较大的图形?在这种情况下,基于其中的“节点”的数量,图形更大或更小。例如,左边有4,右边有2。

public Equivalence<E> mergeClassesContaining(E a, E b) throws IllegalArgumentException {


    if (!inSameClass(a, b)) { //private function to determine if the given parameters are in the same class.
        //need help here.
        return this;
    }
}

这是compressToRoot函数:

private E compressToRoot (E e) throws IllegalArgumentException {
   E node;
   ArrayList<E> nodes = new ArrayList<E>();
    while ((node = parentMap.get(e)) != e)  {
        nodes.add(e);
        e = node;
    }

    for (E element : nodes)
        ((ArrayList<E>) parentMap).set((Integer) node, e);

    return e; 
}

完整代码:

public class HashEquivalence<E> implements Equivalence<E>  {

public Equivalence<E> addSingletonClass (E e) throws IllegalArgumentException {
  if (parentMap.containsKey(e))
    throw new IllegalArgumentException("HashEquivalence.addSingletonClass: e(" +e+ ") already in an equivalence class");
  parentMap.put(e,e);    //its own parent
  rootSizeMap.put(e,1);  //its equivalence class has 1 value in it
  return this;
}

private E compressToRoot (E e) throws IllegalArgumentException {

   E node;
   ArrayList<E> nodes = new ArrayList<E>();
    while ((node = parentMap.get(e)) != e)  {
        nodes.add(e);
        e = node;
    }

    for (E element : nodes)
        ((ArrayList<E>) parentMap).set((Integer) node, e);

    return e; //Allows method to compile
}

public boolean inSameClass(E a, E b) throws IllegalArgumentException {
  if (!parentMap.containsKey(a))
    throw new IllegalArgumentException("HashEquivalence.inSameClass: a(" +a+ ") not in an equivalence class");
  if (!parentMap.containsKey(b))
    throw new IllegalArgumentException("HashEquivalence.inSameClass: b(" +b+ ") not in an equivalence class");

  return compressToRoot(a) == compressToRoot(b);
}


public Equivalence<E> mergeClassesContaining(E a, E b) throws IllegalArgumentException {


  if (!inSameClass(a,b))

return this; 
  }


public Set<Set<E>> allClasses () {
  Map<E,Set<E>> answerMap = new HashMap<E,Set<E>>();
  for (E e : parentMap.keys()) {
    E root = compressToRoot(e);
    Set<E> s = answerMap.get(root);
    if (s == null)
      answerMap.put(root, s = new HashSet<E>());
    s.add(e);
  }

return new HashSet<Set<E>>(1.0,answerMap.values());
}


public int numberOfClasses ()
{return rootSizeMap.size();}


public int numberOfMembers ()
{return parentMap.size();}


private Map<E,Integer> heights () {
  Map<E,Integer> answer = new HashMap<E,Integer>();
  for (E element : parentMap.keys()) {
    E e = element;
    int depth = 0;
    while (parentMap.get(e) != e) {
      e = parentMap.get(e);
      depth++;
    }
    Integer soFar = answer.get(e);
    if (soFar == null || soFar < depth)
      answer.put(e, depth);
  }
  return answer;
}


public int maxHeight () {
  return Collections.max(heights().values());
}


public void showMaps() {
  System.out.println("parentMap   (as list) = " + new ArrayList<Map.Entry<E,E>>(parentMap.entries()));
  System.out.println("rootSizeMap (as list) = " + new ArrayList<Map.Entry<E,Integer>>(rootSizeMap.entries()));
  System.out.println("heightMap   (as list) = " + new ArrayList<Map.Entry<E,Integer>>(heights().entries()));
  System.out.println("max height of tree    = " + maxHeight());
}


private Map<E,E>       parentMap   = new HashMap<E,E>();
private Map<E,Integer> rootSizeMap = new HashMap<E,Integer>();
}

0 个答案:

没有答案