IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 最小生成树算法与代码--C++ -> 正文阅读

[C++知识库]最小生成树算法与代码--C++


前言

摘自wiki

最小生成树其实是最小权重生成树的简称。

一个连通图可能有多个生成树。当图中的边具有权值时,总会有一个生成树的边的权值之和小于或者等于其它生成树的边的权值之和。广义上而言,对于非连通无向图来说,它的每一连通分量同样有最小生成树,它们的并被称为最小生成森林。

以有线电视电缆的架设为例,若只能沿着街道布线,则以街道为边,而路口为顶点,其中必然有一最小生成树能使布线成本最低。

以上选自wiki

算法详情

创建一个优先队列。先选取第一个点,作为起点,将与其连接的所有边加入优先队列。
取队列中权重最小的边,若另一端没有被访问过,则加入树中,并将该节点连接的所有边都放入优先队列。
重复以上工作,直到访问完所有点。

代码

#include <algorithm>
#include <memory>
#include <vector>
#include <utility>
#include <Eigen/Dense>
#include <queue>

class MinimumSpinningTree
{
public:
  std::vector<std::vector<std::size_t>> getTree(Eigen::MatrixXd graph)
  {
    generateMinimumSpinningTree(graph);
    return adjacent_list_;
  }

private:
  void generateMinimumSpinningTree(Eigen::MatrixXd graph);

  std::vector<std::vector<std::size_t>> adjacent_list_;
  std::unique_ptr<GridMap2D> grid_map_ptr_;
  using EdgeWithVertex =
      std::pair<double, std::pair<std::size_t, std::size_t>>;  // <edge_length, <start_vertex, end_vertex>>

  static bool edgePriorityComparator(const EdgeWithVertex& lhs, const EdgeWithVertex& rhs)
  {
    return lhs.first > rhs.first;
  }

  using DistancePriorityQueue =
      std::priority_queue<EdgeWithVertex, std::vector<EdgeWithVertex>, decltype(edgePriorityComparator)*>;
};


void MinimumSpinningTree::generateMinimumSpinningTree(Eigen::MatrixXd graph)
{
  std::size_t node_num = graph.rows();
  adjacent_list_.clear();
  adjacent_list_.resize(node_num);

  std::vector<bool> added_nodes(node_num, false);
  std::size_t nodes_remained_num = graph.rows();

  DistancePriorityQueue candidate_edges{ edgePriorityComparator };

  for (std::size_t i = 1; i < graph.rows(); ++i)
  {
    candidate_edges.push({ graph(0, i), { 0, i } });
  }
  added_nodes[0] = true;
  nodes_remained_num--;

  while (nodes_remained_num)
  {
    auto min_edge = candidate_edges.top().second;
    candidate_edges.pop();
    if (added_nodes[min_edge.second])
    {
      continue;
    }

    added_nodes[min_edge.second] = true;
    nodes_remained_num--;
    adjacent_list_[min_edge.first].push_back(min_edge.second);
    adjacent_list_[min_edge.second].push_back(min_edge.first);
    for (std::size_t i = 1; i < graph.rows(); ++i)
    {
      if (i == min_edge.second)
      {
        continue;
      }
      candidate_edges.push({ graph(i, min_edge.second), { min_edge.second, i } });
    }
  }
}

以上。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-17 15:11:24  更:2021-08-17 15:12:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 0:57:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码