图--offset earliest
中受约束的最短路径问题是,在给定节点G=(V,E)
和汇聚节点s
的情况下,找到从t
到{{1}的最短路径这样路径上消耗的总资源最多为标量s
。图表中的每个弧t
都有一个成本标量R
,并将资源用于标量(i,j)
的调整。路径的成本是构成路径的各个弧的成本之和,并且路径消耗的资源是构成路径的各个弧的资源的总和。已知此问题为c_{ij}
。
解决此问题的大多数实现都使用动态编程方法,它基本上执行一种强力枚举以及其他巧妙的方法来减少搜索量。
使用labelling approach实现动态编程。
我使用了几种不同的方法实现了这个算法,我想确保我是否尽可能高效地进行。
标记方法会创建多个标签,这些标签基本上是从r_{ij}
到其他各个节点的部分路径。算法期间会创建大量标签(注意,问题为NP-HARD
),直到满足停止标准。
每个标签可以表示为s
,如下所示。
NP HARD
随着算法的进行,需要创建和存储上述许多结构。
方法1:
我对此的早期实现计算效率非常低。当需要新标签时,这会涉及struct
结构,并使用struct labels_s {
double current_states[10];
double unscanned_states[10];
int already_visited[100];//If node i is already visited on partial path, already_visited[i] = 1, else 0
int do_not_visit[100];//if node i is not to be visited from this label, do_not_visit[i] = 1; 0 otherwise
struct labels_s* prev;
struct labels_s* next;
};
的成员new
和next
明确地将这些结构保存在链接列表中。
方法2:
而不是prev
struct
,我开始将新结构存储在new
容器中:
structs
要执行此操作,并且由于std::vector
提供对各种标签的整数索引访问权限,vector <labels_s> labels;
的{{1}}和vector
可以更改为prev
和{ {1}}
存储标签涉及以下内容:
next
使用方法2 解决同一问题的计算时间明显优于方法1 。标签仅添加在矢量的末尾。无需在向量中间插入或从向量中删除。
除方法2 以外,还有其他管理这些标签的方法吗?
我主要关注的是方法2 的第3步。由于struct labels_s
创建了int prev;
的副本,这种复制操作是否代价高昂,是否可以避免这种情况?
我正在考虑的一个替代方案是维护一个指向标签结构的指针向量,而不是像我目前那样使用标签结构的向量。但在我看来,保持指向标签结构的指针向量应该不比方法1 更有效。
赞赏任何意见。
答案 0 :(得分:2)
在C ++ 11中,您可以使用emplace_back
(cppreference)在向量的末尾构建标签。你可以这样做:
labels.emplace_back(); // default construct a new label at the end of labels
// then populate members like this:
labels.back().member1 = val1;
根据您的使用案例,您还可以为labels_s
创建一个构造函数,该构造函数获取成员的所有值并初始化它们。在这种情况下,你可以写
labels.emplace_back(val1, val2, …);
完成。
除此之外,您应该在填充reserve
之前慷慨地labels
(cppreference),以避免频繁重新分配。