图遍历中寻找最小路径的有效方法

问题描述

我有一大组长度相同的二进制字符串。我知道每个二进制字符串的 1 步邻域(意思是,所有其他二进制字符串仅相差 1 位)。这种关系本质上创建了一个图表。现在,从图中的任何节点开始,我想知道在基于某个派生值(而不是基于二进制字符串)到达不同节点之前我必须采取的最小步骤数是多少。我正在使用一些虚拟函数 GetABC() 在我下面的示例中)。如果我们在找到不同的节点之前遇到了死胡同,我们假设到达不同节点的最小步数是无限的。死胡同是无法访问新节点(基于访问节点的历史记录)。如果我们的整个种群具有相同的派生值,那么最坏的情况是我们将访问每个节点然后返回无穷大 (-1)。

我的第一次尝试是使用递归函数,并通过传递对访问节点向量的引用来通过递归跟踪所有访问过的节点。它适用于小数据集,但对于 100 万个二进制字符串,我遇到了堆栈溢出错误(字面意思)。

然后,我重构了我的代码以在循环中运行,而不是通过迭代构建要访问的邻居集,然后遍历所有邻居并检查是否有不同的派生值(GetABC()),然后从所有邻居重新开始我们刚刚访问过的邻居。同样,在一个小数据集上工作,但有 100 万条记录,我的代码已经运行了 4 天,但仍未完成(在 12 个线程上使用并行 for_each 在所有节点上进行此分析)。

//Previously had this function as a recursive algorithm,but it triggered stack overflow on big dataset
int MyClass::FindDifferentNodeInNeighborhood2(uint64_t node_hash) {
    std::vector<uint64_t> visited;//init empty visited vector
    visited.push_back(node_hash);

    int level = 0;
    bool found_diff_node = false;
    std::unordered_map<int,std::vector<std::pair<uint64_t,uint64_t>>> to_visit;//<level,vec<node_to_visit,parent_node>>

    to_visit[level].push_back(std::make_pair(node_hash,0));//0 because no parent. Not used in first loop anyway so the value doesn't matter

    while (!found_diff_node && !to_visit[level].empty()) {
        for (auto n : to_visit[level]) {
            //_negihborhood is a member variable of MyClass defined as
            //std::unordered_map<uint64_t,std::unordered_set<uint64_t>> _neighborhood;
            for (const auto neighbor : _neighborhood[n.first]) {
                //make sure we didn't visit this neighbor already
                if (std::find(visited.begin(),visited.end(),neighbor) == visited.end()) {
                    //if not,add to next set of node to visit
                    to_visit[level + 1].push_back(std::make_pair(neighbor,n.first));
                }
            }
        }
        level++;

        for (auto n : to_visit[level]) {
            //auto node = n.first;
            //auto parent = n.second;
            visited.push_back(n.first);
            //_population is the map of the actual binary strings objects
            //We retrieve the object using it's hash
            //GetABC() is just a function that gets a specific value from the node
            if (_population[n.first].GetABC() != _population[n.second].GetABC()) {
                found_diff_node = true;
                break;
            }
        }
    }

    if (!found_diff_node) {
        return -1;
    }
    return level;
}

我会进一步调试,看看这是否不是无限循环的问题,但我想我应该在这里问一下我是否忽略了一些可以实现这一点的简单算法。

谢谢

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)