我有一个图表存储为邻接列表。 vertex属性包含int ID,edge属性包含4x4矩阵和权重;
在测试用例中,图形是一个3顶点图形,边缘连接每对顶点(一个完整的图形)。
我有一个边缘描述符PathType
的向量,表示一个路径,我正在迭代它并访问每个边缘及其属性RelationshipEdge
,如下所示。
for(PathType::iterator pathIterator = path.begin(); pathIterator != path.end(); ++pathIterator){
edge_t edge = *pathIterator;
RelationshipEdge rEdge = m_graph[edge];
int sourceID = m_graph[boost::source(edge, m_graph)].id;
int destID = m_graph[boost::target(edge, m_graph)].id;
但是,有时执行此操作时,返回的RelationshipEdge
包含错误边缘的数据。
例如,检查edge
会显示m_source
为1和m_target
为2.如果我检查图表并找到包含源1和目标2的边缘,则权重为3,矩阵输入。然而,rEdge的权重为1,并且矩阵不同。这些值实际上对应于源0和目标1的边缘。
我是否正确访问了边缘属性?
我的图表类型的定义是:
typedef boost::adjacency_list<
boost::vecS, boost::vecS, boost::undirectedS, MarkerVertex, RelationshipEdge>
CorrelationAdjacencyList;
答案 0 :(得分:2)
我相信你的错误来自代码库中的其他地方。
我把这个简单的代码放在一起测试边缘访问和类似图表上的顺序,一切都按预期工作。
如上所述,可以手动维护罪犯edge_descriptors
或vertex_descriptors
。或者也许你的路径矢量初始化或构建。
#include <iostream>
#include <algorithm>
#include <vector>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
using namespace std;
enum edge_t {A,B};
struct MarkerVertex{
std::string id;
};
struct RelationshipEdge{
std::string id;
};
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
MarkerVertex, RelationshipEdge> CorrelationAdjacencyList;
typedef boost::graph_traits<CorrelationAdjacencyList>::edge_descriptor Edge;
typedef boost::graph_traits<CorrelationAdjacencyList>::vertex_descriptor Vertex;
typedef vector<Edge> PathType;
void printPath(PathType &p, CorrelationAdjacencyList &g){
cout << "print path" << endl;
for(PathType::iterator pi = p.begin(); pi != p.end(); ++pi){
Edge e = *pi;
Vertex s = boost::source(e,g);
Vertex t = boost::target(e,g);
cout << g[s].id << "\t"
<< g[e].id << "\t"
<< g[t].id << endl;
bool isFound;
Edge eForward;
boost::tie(eForward,isFound) = boost::edge(s,t,g);
cout << "forward " << g[eForward].id << "\t" << isFound << endl;
Edge eBackward;
boost::tie(eBackward,isFound) = boost::edge(t,s,g);
cout << "backward " << g[eBackward].id << "\t" << isFound << endl;
}
}
int main(int argc, char* argv[]){
CorrelationAdjacencyList graph;
Vertex a = boost::add_vertex(graph); graph[a].id = "a";
Vertex b = boost::add_vertex(graph); graph[b].id = "b";
Vertex c = boost::add_vertex(graph); graph[c].id = "c";
Edge e1 = boost::add_edge(a,b,graph).first; graph[e1].id = "e1";
Edge e2 = boost::add_edge(b,c,graph).first; graph[e2].id = "e2";
Edge e3 = boost::add_edge(c,a,graph).first; graph[e3].id = "e3";
PathType path1,path2,path3;
path1.push_back(e1);
path1.push_back(e2);
path1.push_back(e3);
path2.push_back(e2);
path2.push_back(e3);
path2.push_back(e1);
path3.push_back(e3);
path3.push_back(e2);
path3.push_back(e1);
printPath(path1,graph);
cout << endl;
printPath(path2,graph);
cout << endl;
printPath(path3,graph);
cin.get();
}
答案 1 :(得分:0)
如果没有进一步的信息,我可以做出有根据的猜测,即使用vecS
个容器并且迭代器/引用已经失效。
在插入/删除边/顶点时会发生这种情况。
答案 2 :(得分:0)
以下是我找到的解决方案,但我并不相信我完全理解为什么原始方法没有。
我用
替换了上面的代码map.on('zoomend', function() {
var currentZoom = map.getZoom();
overlayGroup.clearLayers() //remove existing
overlayGroup.addLayer(myZoomLevelMapping[currentZoom]) //add layer for this zoom level.
})
for(PathType::iterator pathIterator = path.begin(); pathIterator != path.end(); ++pathIterator){
edge_t edge = *pathIterator;
int sourceID = m_graph[boost::source(edge, m_graph)].id;
int destID = m_graph[boost::target(edge, m_graph)].id;
int lowerID, higherID;
if (sourceID < destID){
lowerID = sourceID;
higherID = destID;
} else {
lowerID = destID;
higherID = sourceID;
}
edge_t edge2 = m_edgeDescriptorsByEndpoints.at(make_pair(lowerID, higherID));
RelationshipEdge rEdge = m_graph[edge2];
是一对顶点ID到边描述符的映射。
所以我采用边缘描述符,获取源顶点和目标顶点的ID,从地图中找到相应的边缘描述符,然后获取该边缘的属性。
不完全是一个令人满意的解决方案,但它确实有效,因为到目前为止我已经能够进行测试。
修改强>
我按照@sehe的建议调用m_edgeDescriptorsByEndpoints
来调用我的地图,所以代码如下:
boost::edge(u,v,g)
这段代码仍然会导致rEdge包含正确的属性,这似乎很奇怪,因为我认为查询边缘顶点的图形,然后查询图形中连接这些顶点的边缘总是给你完全相同的边缘。