C 使用Boost库的C 最小跨越树
c++ Prim minimum spanning tree using Boost Library
我正在研究一个项目,我需要在我的教授将提供的输入文件上实现dijkstra,prim和*算法。我已经成功编写了Dijkstra的工作代码,但是我正在撞墙,试图使我的图形也为Prim的工作。我觉得我的问题没有正确地掌握树地图来从中获取我的信息,但我无法真正围绕问题所在,任何帮助都将不胜感激。
边缘和verts的结构和图形特征:
typedef boost::adjacency_list_traits<vecS, vecS, undirectedS, listS> GraphTraits;
// type 'Vertex' identifies each vertex uniquely:
typedef GraphTraits::vertex_descriptor Vertex;
// Property type associated to each vertex:
struct VertexProperty {
string name; // Name of vertex (i.e., "location")
Vertex predecessor; // Predecessor along optimal path.
double distance; // Distance to the goal, along shortest path.
default_color_type color; // for use by dijkstra.
VertexProperty(const string& aName = "") : name(aName) { };
};
// Property type associated to each edge:
struct EdgeProperty {
double weight; // distance to travel along this edge.
EdgeProperty(double aWeight = 0.0) : weight(aWeight) { };
};
// Type of the graph used:
typedef adjacency_list<vecS, vecS, undirectedS, VertexProperty, EdgeProperty> Graph;
// Create a global graph object 'g'
Graph g;
// This is a visitor for the dijkstra algorithm. This visitor does nothing special.
struct do_nothing_dijkstra_visitor {
template <typename Vertex, typename Graph>
void initialize_vertex(Vertex u, const Graph& g) const { };
template <typename Vertex, typename Graph>
void examine_vertex(Vertex u, const Graph& g) const { };
template <typename Edge, typename Graph>
void examine_edge(Edge e, const Graph& g) const { };
template <typename Vertex, typename Graph>
void discover_vertex(Vertex u, const Graph& g) const { };
template <typename Edge, typename Graph>
void edge_relaxed(Edge e, const Graph& g) const { };
template <typename Edge, typename Graph>
void edge_not_relaxed(Edge e, const Graph& g) const { };
template <typename Vertex, typename Graph>
void finish_vertex(Vertex u, const Graph& g) const { };
};
变量:
string tempName1, tempName2, tempString, data2;
int weight;
string inputFile;
int choice;
Vertex cur_v, start_v, goal_v;
map<string, Vertex> name2v, name1v;
double totalDist, tempDist;
int numVert = 0;
基于上传文件的图形构造:
//build graph based on file loaded
getline(fin, tempString);
getline(fin, tempString);
stringstream tempSS(tempString);
while (getline(tempSS, tempName1, ',')) {
name2v[tempName1] = add_vertex(VertexProperty(tempName1), g);
numVert++;
}
getline(fin, tempString);
while (getline(fin, tempString)) {
tempString.erase(tempString.begin(), tempString.begin() + tempString.find('(') + 1);
tempString.erase(tempString.begin() + tempString.find(')'), tempString.end());
stringstream temp_ss(tempString);
getline(temp_ss, tempName1, ',');
getline(temp_ss, tempName2, ',');
temp_ss >> weight;
add_edge(name2v[tempName1], name2v[tempName2], EdgeProperty(weight), g);
}
name1v = name2v;
prim的呼叫:
cout << "Please enter the Vertex you would like to start at: ";
cin >> tempName1;
transform(tempName1.begin(), tempName1.end(), tempName1.begin(), ::toupper);
start_v = name1v[tempName1];
prim_minimum_spanning_tree(g, start_v,
get(&VertexProperty::predecessor, g),
get(&VertexProperty::distance, g),
get(&EdgeProperty::weight, g),
identity_property_map(),
do_nothing_dijkstra_visitor());
我只是尝试包括重要的代码。就像我说的那样,该代码适用于Dijkstra,但我不确定如何使其适用于Prim的。我认为我需要在fitterxproperty的结构中添加更多,或者有一个地图来存储最小跨越树。预先感谢。
我看不到您到底在问什么(除了代码样式和质量问题外)。
在这里,注意
- 减少的访客
- 删除了混乱的评论
- 当然,我在这里生成一个随机图,因为我们没有您的输入
活在coliru
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/prim_minimum_spanning_tree.hpp>
#include <boost/graph/random.hpp>
#include <fstream>
#include <map>
#include <random>
#include <sstream>
typedef boost::adjacency_list_traits<boost::vecS, boost::vecS, boost::undirectedS> GraphTraits;
typedef GraphTraits::vertex_descriptor Vertex;
struct DijkstraStuff {
Vertex predecessor;
double distance;
boost::default_color_type color; // for use by dijkstra.
};
struct VertexProperty : DijkstraStuff {
std::string name;
VertexProperty(const std::string &aName = "") : name(aName){};
};
struct EdgeProperty {
double weight; // distance to travel along this edge.
EdgeProperty(double aWeight = 0.0) : weight(aWeight){};
};
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, VertexProperty, EdgeProperty> Graph;
struct do_nothing_dijkstra_visitor : boost::default_dijkstra_visitor {};
int main() {
Graph g;
std::map<std::string, Vertex> name_map;
// read graph (random for now)
{
std::mt19937 prng{ 42 };
generate_random_graph(g, 10, 20, prng);
for (auto vd : boost::make_iterator_range(vertices(g))) {
name_map[g[vd].name = "NAME" + std::to_string(vd)] = vd;
}
std::uniform_real_distribution<double> weight_dist(0, 1);
for (auto ed : boost::make_iterator_range(edges(g))) {
g[ed].weight = weight_dist(prng);
}
}
print_graph(g, get(&VertexProperty::name, g));
Graph::vertex_descriptor start_v;
std::cout << "Please enter the Vertex you would like to start at: ";
{
std::string startName;
std::cin >> startName;
std::transform(startName.begin(), startName.end(), startName.begin(),
[](uint8_t ch) { return std::toupper(ch); });
start_v = name_map.at(startName);
}
boost::prim_minimum_spanning_tree(g, start_v, get(&VertexProperty::predecessor, g),
get(&VertexProperty::distance, g), get(&EdgeProperty::weight, g),
boost::identity_property_map(), do_nothing_dijkstra_visitor());
}
打印结果
将结果的MST编码为前身映射。打印如下:
for (auto vd : boost::make_iterator_range(vertices(g))) {
auto p = g[vd].predecessor;
std::cout << "Pred of " << g[vd].name << " is " << g[p].name << "n";
}
(这是为了简单起见,假设所有顶点都在MST中。这与假设您在输入中没有连接的顶点相同)
打印(对于给定的随机种子和启动顶点):
Pred of NAME1 is NAME9
Pred of NAME2 is NAME2
Pred of NAME3 is NAME6
Pred of NAME4 is NAME1
Pred of NAME5 is NAME6
Pred of NAME6 is NAME1
Pred of NAME7 is NAME3
Pred of NAME8 is NAME7
Pred of NAME9 is NAME0
相关文章:
- c++库的公共头文件中应该包含什么
- 序列化,没有库的整数,得到奇怪的结果
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身
- 针对遗留库的链接:来自预制makefile的-lgfortranbegin
- 将 OpenCV 与 CMAKE 中的项目一起构建为第三方库的正确方法
- Android Studio 中带有静态库的原生C++代码
- 如何在OpenSSL库的名称中添加后缀'd'?
- 在OSX上使用CMake将Adobe的XMP工具包构建为共享库的最简单方法是什么?
- 为什么提升图库的 read_graphviz() 函数会改变节点的索引
- 在Visual Studio C++项目中包含源库的正确方法是什么?
- 良好做法:如何定义用于编译的外部库的路径
- 使用 CImg 库的 std::min 和 std::max 的编译问题
- 使用指针在存在特征库的情况下动态分配 c++ 中的矩阵
- CMake:我们可以为一组不形成可执行文件或库的特定文件指定包含目录吗?
- 将共享库的搜索路径更改为生成文件中提供的 rpath
- 编译依赖于 QTCore 库的 WASM
- 在不使用字符串库的情况下输入字符*
- 如何公开库的枚举,以便我的代码不必键入整个命名空间来使用该枚举?
- 如何在公共头文件中向库的用户公开枚举,同时在内部使用它?
- C 使用Boost库的C 最小跨越树