全合并搜索优化

时间:2012-12-22 00:04:42

标签: c++ algorithm search optimization recursion

假设存在大小为N的向量VA,并且每个元素是类型T的另一个向量。对类型T进行操作并返回类型T的新值,即bool merge(T a, T b, T &ret);。如果可以合并a和c,则将结果存储在ret中并返回true;否则,返回false。合并操作具有反思性和传递性。

如果出现以下情况,则会找到解决方案:

  1. ∃x 0 ,x 1 ,...,x N-1 。合并(VA [0] [x 0 ],VA [1] [x 1 ],合并(VA [2] [x 2 ],...,合并(VA [N-2] [x N-2 ],VA [N-1] [x N-1 ],ret) ...));
  2. 可以合并来自N-1(非N )子矢量的任何元素(选择任何N-1只有一个例外)。
  3. 例如: VA的大小为3.元素a可以与元素b合并,结果为c。元素c可以与元素d合并,结果为e。

    • VA [0] = {a}
    • VA [1] = {b,q}
    • VA [2] = {d,r}

    以上示例中的所有解决方案均为:{a,b},{a,d},{b,d},{a,b,d}。

    任务是找到给定向量VA中的所有解。

    我的C ++代码是:

    void findAll(unsigned int step, unsigned int size, const T pUnifier, int hole_id) {
      if(step == size) printOneResult(pUnifier);
      else {
        _path[step] = -1;
        findAll(step + 1, pUnifier, step);
      }
      std::vector<T> vec = VA[step];
      for(std::vector<T>::const_iterator it = vec.begin(); it < vec.end(); it++) {
        T nextUnifier();
        if( merge( *it, pUnifier, nextUnifier )) {
           _path[lit_id] = it->getID();
           findAll(step + 1, nextUnifier, hole_id);
        }
      }
    }
    

    代码包含递归调用;但是,它不是尾递归。它在实践中运行缓慢。实际上,VA的大小可能是数百个,每个子矢量大小也是数百个。我想知道它是否可以优化。

    非常感谢。

2 个答案:

答案 0 :(得分:1)

如果我正确理解您的代码,那么您正在进行(递归)强力搜索。这样效率不高,因为您可以获得有关搜索空间的一些信息。

我认为这里的好候选人是A* algorithm。您可以使用当前最大链尺寸作为启发式,或者甚至是链尺寸的平方和。

答案 1 :(得分:-1)

为了改进代码,在使用向量时,应该使用[]运算符,使用int计数器而不是简单的迭代器,这要慢得多。 您可以通过最小化函数调用我的任何一个循环来改进它,就像之前堆叠您将使用的值一样。 既然你没有解释真正的T_VEC是什么,我就不会写完整的无迭代器版本,但这应该是关于速度的一个很好的补充。