【发布时间】:2018-10-22 15:17:24
【问题描述】:
我有一个节点列表,每个节点都分解为更多节点。例如
- Node0 = w01 * Node1 + w02 * Node2 + w03 * Node3
- Node1 = w12 * Node2 + w14 * Node4
因此,我们有 Node0 = w01*w12 * Node2 + w03 * Node3 + w01*w14 Node4。
我的 C++ 代码为给定的一组权重分解执行上述聚合/分解/合并如下所示。但是,我觉得有很多优化要做。仅举一个例子,我循环遍历topWeights 的键并将它们收集到topNodeNames,这似乎非常低效。
是否有任何 STL 算法可以帮助我加快速度,并可能避免不必要的复制?
#include <string>
#include <unordered_map>
template<class T, class U> using umap = std::unordered_map<T, U>;
umap<std::string, double> getWeights(const std::string& nodeName, const umap<std::string, umap<std::string, double>>& weightTrees)
{
const auto it = weightTrees.find(nodeName);
if (it == weightTrees.end())
return umap<std::string, double>();
umap<std::string, double> topWeights = it->second;
std::vector<std::string> topNodeNames;
for (const auto& kv : topWeights)
topNodeNames.push_back(kv.first);
for (const std::string& topNodeName : topNodeNames)
{
umap<std::string, double> subWeights = getWeights(topNodeName, weightTrees);
if (subWeights.size() > 0)
{
const double topWeight = topWeights[topNodeName];
topWeights.erase(topNodeName);
for (const auto& subWeight : subWeights)
{
const auto it = topWeights.find(subWeight.first);
if (it == topWeights.end())
topWeights[subWeight.first] = topWeight * subWeight.second;
else
it->second += topWeight * subWeight.second;
}
}
}
return topWeights;
}
int main()
{
umap<std::string, umap<std::string, double>> weightTrees = {{ "Node0", {{ "Node1",0.5 },{ "Node2",0.3 },{ "Node3",0.2 }} },
{ "Node1", {{ "Node2",0.1 },{ "Node4",0.9 }} }};
umap<std::string, double> w = getWeights("Node0", weightTrees); // gives {Node2: 0.35, Node3: 0.20, Node4: 0.45}
}
【问题讨论】:
-
在循环依赖的情况下会发生什么(我假设没有)?您的真实用例在不同分支之间是否有许多公共节点?
-
循环依赖永远不应该发生(在真实的情况下)。但我同意,这很好,所以对此进行某种安全检查。至于问题 2,它确实可以改变。
-
层数没有限制。一个节点可以分解成另一个,分解成另一个,分解成两个,等等。
-
节点已经有订单了吗? (即
NodeN从不依赖节点NodeK和K < N)?编辑:是的,当我问上一个问题时,我误解了规范。 -
@MaxLanghof 不,你也可以调用节点:ABC、Node23、Server10、TestNode等
标签: c++ algorithm merge c++17 unordered-map