假设存在大小为N的向量VA,并且每个元素是类型T的另一个向量。对类型T进行操作并返回类型T的新值,即bool merge(T a, T b, T &ret);
。如果可以合并a和c,则将结果存储在ret
中并返回true;否则,返回false。合并操作具有反思性和传递性。
如果出现以下情况,则会找到解决方案:
例如: VA的大小为3.元素a可以与元素b合并,结果为c。元素c可以与元素d合并,结果为e。
以上示例中的所有解决方案均为:{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的大小可能是数百个,每个子矢量大小也是数百个。我想知道它是否可以优化。
非常感谢。
答案 0 :(得分:1)
如果我正确理解您的代码,那么您正在进行(递归)强力搜索。这样效率不高,因为您可以获得有关搜索空间的一些信息。
我认为这里的好候选人是A* algorithm。您可以使用当前最大链尺寸作为启发式,或者甚至是链尺寸的平方和。
答案 1 :(得分:-1)
为了改进代码,在使用向量时,应该使用[]运算符,使用int
计数器而不是简单的迭代器,这要慢得多。
您可以通过最小化函数调用我的任何一个循环来改进它,就像之前堆叠您将使用的值一样。
既然你没有解释真正的T_VEC是什么,我就不会写完整的无迭代器版本,但这应该是关于速度的一个很好的补充。