【图论】图的C++实现代码

在这个例程中我们用类实现了节点、(无向图)连边、无向图,实现了节点度的计算、无向图聚类系数计算、度分布统计、无向图的Dijkstra算法(已知起止点计算最短路的算法)

#include <iostream>
#include<vector>
#include<set>
#include<unordered_map>
using namespace std;class Edge
{
public:int v1;int v2;int weight;Edge(int v1, int v2, int w){this->v1 = v1;this->v2 = v2;this->weight = w;}
};class DJPathInfo // 存放已知最短路
{
public:vector<vector<int>> shortest_path;vector<int> shortest_path_len;DJPathInfo(int n){vector<int> empty;this->shortest_path=vector<vector<int>>(n, empty);this->shortest_path_len= vector<int>(n, 0);}
};class Node
{
public:std::vector<Edge> edges;int id;Node(int i){this->id = i;}int degree(){return this->edges.size();}vector<int> neighbors(){vector<int> res;if (this->edges.size() > 0){for (auto edge : this->edges){if (edge.v1 == this->id) res.push_back(edge.v2);else res.push_back(edge.v1);}return res;}else return res;}float cluster_coeff(vector<vector<bool>> adj_mat){int num_neighbor = this->edges.size() - 1;if (num_neighbor < 2) return 0;vector<int> neighbors = this->neighbors();float E = 0; //邻居之间的边数for (auto i : neighbors){for (auto j : neighbors){if (i >= j) continue;if (adj_mat[i][j] == true) E++;}}cout << 2 * E / (neighbors.size() * (neighbors.size() - 1)) << endl;return 2 * E / (neighbors.size() * (neighbors.size() - 1));}
};class Graph
{
public:vector<vector<bool>> adj_mat;vector<vector<float>> w_mat;int node_num;vector<Edge> edges;vector<Node> nodes;Graph(vector<vector<bool>> A, vector<vector<float>> W){this->adj_mat = A;this->w_mat = W;this->node_num = A.size();for (int i = 0; i < node_num; i++) this->nodes.push_back(Node(i));for (int i = 0; i < node_num; i++)for (int j = 0; j < i; j++){if (A[i][j] == true) this->add_edge(i, j, W[i][j]);}}Graph(int n){vector<float> zero(n, 0);vector<bool> all_false(n, false);vector<vector<bool>> A(n, all_false);vector<vector<float>> W(n, zero);this->adj_mat = A;this->w_mat = W;this->node_num = A.size();for (int i = 0; i < node_num; i++) this->nodes.push_back(Node(i));for (int i = 0; i < node_num; i++)for (int j = 0; j < i; j++){if (A[i][j] == true) this->add_edge(i, j, W[i][j]);}}void add_edge(int id1, int id2, int weight){Edge e = Edge(id1, id2, weight);this->adj_mat[id1][id2] = true;this->adj_mat[id2][id1] = true;this->w_mat[id1][id2] = weight;this->w_mat[id2][id1] = weight;this->edges.push_back(e);this->nodes[id1].edges.push_back(e);this->nodes[id2].edges.push_back(e);}void tell_info(){for (auto v : this->nodes){std::cout << "Node ID:" << v.id << std::endl;std::cout << "Neighbor/Weight:";for (auto i : v.neighbors()) cout <<'(' << i<<','<< this->w_mat[v.id][i] << ')' << ',';std::cout<<std::endl;}}vector<int> DJ(int s, int dest) // Dijkstra算法{DJPathInfo info(this->nodes.size());vector<int> res = {s};set<int> S;S.insert(s);set<int> U;for (auto v : this->nodes[s].neighbors()) U.insert(v);if (U.size() == 0) return res;for (auto v : U){info.shortest_path[v].push_back(v);info.shortest_path_len[v] = this->w_mat[s][v];}info.shortest_path_len[s] = 0;while (U.size() != 0){int n = *U.begin();int n_len = info.shortest_path_len[n];for (auto it = U.begin(); it != U.end(); it++){if (info.shortest_path_len[n] > info.shortest_path_len[*it]){n = *it;n_len = info.shortest_path_len[*it];}}S.insert(n);U.erase(n);for (auto v : this->nodes[n].neighbors()){if (S.find(v) != S.end()) continue;U.insert(v);if (info.shortest_path[v].size() == 0){info.shortest_path[v] = info.shortest_path[n];info.shortest_path[v].push_back(v);info.shortest_path_len[v] = info.shortest_path_len[n] + this->w_mat[n][v];continue;}if (info.shortest_path_len[n] + this->w_mat[n][v] < info.shortest_path_len[v]){info.shortest_path[v] = info.shortest_path[n];info.shortest_path[v].push_back(v);info.shortest_path_len[v] = info.shortest_path_len[n] + this->w_mat[n][v];}}}if (S.find(dest) != S.end()){for (auto v : info.shortest_path[dest]) res.push_back(v);info.shortest_path_len[dest];}return res;}float cluster_coeff(){float res=0;for (auto node : this->nodes) res += node.cluster_coeff(this->adj_mat);return res / float(this->nodes.size());}void degree_distribution() // 度分布{vector<float> res;unordered_map<int, int> degree_count;for (auto v : this->nodes){degree_count.emplace(v.degree(), 0);}for (auto v : this->nodes){degree_count[v.degree()]++;}for (auto it : degree_count){std::cout << "degree =" << it.first << ', '<<" prob=" << float(it.second) / this->nodes.size() << endl;}}
};int main()
{Graph G = Graph(11);G.add_edge(0, 1, 2);G.add_edge(0, 2, 9);G.add_edge(0, 3, 1);G.add_edge(1, 4, 1);G.add_edge(1, 2, 6);G.add_edge(2, 4, 5);G.add_edge(2, 5, 1);G.add_edge(2, 6, 2);G.add_edge(2, 3, 7);G.add_edge(3, 6, 9);G.add_edge(4, 7, 2);G.add_edge(4, 8, 9);G.add_edge(4, 5, 3);G.add_edge(5, 8, 6);G.add_edge(5, 6, 4);G.add_edge(6, 8, 3);G.add_edge(6, 9, 1);G.add_edge(7, 8, 7);G.add_edge(7, 10, 9);G.add_edge(8, 10, 2);G.add_edge(8, 9, 1);G.add_edge(9, 10, 4);G.tell_info();cout << "Djkstra Test: shortest 0 -> 10: ";for (const auto& p : G.DJ(0, 10)) cout << p << ',';cout<<endl;cout << "clustring coefficient=" << G.cluster_coeff() << endl;cout << "degree distribution:"  << endl;G.degree_distribution();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/60022.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java:二维数组

目录 1. 二维数组的基础格式 1.1 二维数组变量的创建 —— 3种形式 1.2 二维数组的初始化 \1 动态初始化 \2 静态初始化 2. 二维数组的大小 和 内存分配 3. 二维数组的不规则初始化 4. 遍历二维数组 4.1 for循环 ​编辑 4.2 for-each循环 5. 二维数组 与 方法 5.1…

Code::Blocks 24.10 全中文优化完整版

Code::Blocks&#xff08;或者叫做 CodeBlocks&#xff09;是一款开放源代码、跨平台的集成开发环境&#xff08;IDE&#xff09;&#xff0c;通过配置不同的编程语言编译器&#xff0c;可以用于多种编程语言程序开发。 网上有很多文章介绍 Code::Blocks 的安装&#xff0c;通…

分组校验在Spring中的应用详解

目录 前言1. 什么是分组校验2. 分组校验的基本原理3. 分组校验的实现步骤3.1 定义分组接口3.2 在校验项中指定分组3.3 校验时指定要校验的分组3.4 默认分组和分组的继承 4. 分组校验的优势和适用场景4.1 优势4.2 适用场景 5. 常见问题与解决方案5.1 校验未生效5.2 无法识别默认…

【C++滑动窗口】1297. 子串的最大出现次数|1748

本文涉及的基础知识点 C算法&#xff1a;滑动窗口及双指针总结 固定长度滑动窗口 LeetCode1297. 子串的最大出现次数 给你一个字符串 s &#xff0c;请你返回满足以下条件且出现次数最大的 任意 子串的出现次数&#xff1a; 子串中不同字母的数目必须小于等于 maxLetters 。…

【C++练习】使用海伦公式计算三角形面积

编写并调试一个计算三角形面积的程序 要求&#xff1a; 使用海伦公式&#xff08;Herons Formula&#xff09;来计算三角形的面积。程序需要从用户那里输入三角形的三边长&#xff08;实数类型&#xff09;。输出计算得到的三角形面积&#xff0c;结果保留默认精度。提示用户…

计算机网络:网络层 —— 移动 IP 技术

文章目录 移动性对因特网应用的影响移动 IP 相关基本概念移动IP技术的基本工作原理代理发现与注册固定主机向移动主机发送IP数据报移动主机向固定主机发送IP数据报同址转交地址方式三角形路由问题 移动性对因特网应用的影响 我们列举如下三个应用场景说明移动性对因特网应用的…

鸿蒙多线程开发——Worker多线程

1、概 述 1.1、基本介绍 Worker主要作用是为应用程序提供一个多线程的运行环境&#xff0c;可满足应用程序在执行过程中与主线程分离&#xff0c;在后台线程中运行一个脚本进行耗时操作&#xff0c;极大避免类似于计算密集型或高延迟的任务阻塞主线程的运行。 创建Worker的线…

【大数据学习 | kafka】消费者的分区分配规则

1. 概述 上面我们提到过&#xff0c;消费者有的时候会少于或者多于分区的个数&#xff0c;那么如果消费者少了有的消费者要消费多个分区的数据&#xff0c;如果消费者多了&#xff0c;有的消费者就可能没有分区的数据消费。 那么这个关系是如何分配的呢&#xff1f; 现在我们…

Python接口自动化测试自学指南(项目实战)

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 接口自动化测试是指通过编写程序来模拟用户的行为&#xff0c;对接口进行自动化测试。Python是一种流行的编程语言&#xff0c;它在接口自动化测试中得到了广…

Redis - 哨兵(Sentinel)

Redis 的主从复制模式下&#xff0c;⼀旦主节点由于故障不能提供服务&#xff0c;需要⼈⼯进⾏主从切换&#xff0c;同时⼤量 的客⼾端需要被通知切换到新的主节点上&#xff0c;对于上了⼀定规模的应⽤来说&#xff0c;这种⽅案是⽆法接受的&#xff0c; 于是Redis从2.8开始提…

24年配置CUDA12.4,Pytorch2.5.1,CUDAnn9.5运行环境

没什么好介绍的&#xff0c;直接说了。 下载 首先打开命令行&#xff0c;输入代码查看显卡最高支持的cuda版本&#xff0c;下载的版本不要高于该版本 nvidia-smi PyTorch 插件这个是PyTorch下载地址&#xff0c;就按照我这么选CUDA版本就选最新的&#xff0c;看好绿框里的CU…

debian系统安装qt的时候 显示xcb相关文件缺失

如果是安装之后的问题 我们可以选择使用ldd的命令查看当前依赖的so那些文件确实 ldd /home/yinsir/Qt/5.15.2/gcc_64/plugins/platforms/libqxcb.so 本人在进行打包的时候 出现则会个报错 ERROR: ldd outputLine: “libxcb-util.so.1 > not found” ERROR: for binary: “/…

找工作就上万码优才,海量技术岗位等你来

已至岁末&#xff0c;不论你将实习&#xff0c;或正在求职&#xff0c;求职平台千千万万&#xff0c;但简历如落叶般无人问津。 是否因未找到理想职位而心生焦虑&#xff1f;别急&#xff0c;万码优才在这里&#xff0c;为你点亮职业之路的明灯&#xff01; 今天给大家推荐一…

⭐SmartControl: Enhancing ControlNet for Handling Rough Visual Conditions

目录 0 Abstract 1 Motivation 2 Related Work 2.1 Text-to-Image Diffusion Model 2.2 Controllable Text-to-Image Generation 2.3 ControlNet 2.4 Control Scale Exploration 3 Method 3.1 Framework 3.2 Control Scale Predictor 3.3 Unaligned Data Constructi…

vue3 + element-plus 的 upload + axios + django 文件上传并保存

之前在网上搜了好多教程&#xff0c;一直没有找到合适自己的&#xff0c;要么只有前端部分没有后端&#xff0c;要么就是写的不是很明白。所以还得靠自己摸索出来后&#xff0c;来此记录一下整个过程。 其实就是不要用默认的 action&#xff0c;要手动实现上传方式 http-reque…

更改Ubuntu22.04锁屏壁纸

更改Ubuntu22.04锁屏壁纸 sudo apt install gnome-shell-extensions gnome-shell-extension-manager安装Gnome Shell 扩展管理器后&#xff0c;打开“扩展管理器”并使用搜索栏找到“锁屏背景”扩展

SDL打开YUV视频

文章目录 问题1&#xff1a;如何控制帧率&#xff1f;问题2&#xff1a;如何触发退出事件&#xff1f;问题3&#xff1a;如何实时调整视频窗口的大小问题4&#xff1a;YUV如何一次读取一帧的数据&#xff1f; 问题1&#xff1a;如何控制帧率&#xff1f; 单独用一个子线程给主线…

SQL server 中 CROSS APPLY的使用

CROSS APPLY 是 SQL Server 中的一个操作符&#xff0c;用于将一个表表达式&#xff08;如子查询、函数等&#xff09;与外部表进行连接。CROSS APPLY 类似于 INNER JOIN&#xff0c;但它允许你在一个查询中多次引用外部表的行&#xff0c;并且可以动态地生成结果集。 基本语法…

【算法】Floyd多源最短路径算法

目录 一、概念 二、思路 三、代码 一、概念 在前面的学习中&#xff0c;我们已经接触了Dijkstra、Bellman-Ford等单源最短路径算法。但首先我们要知道何为单源最短路径&#xff0c;何为多源最短路径 单源最短路径&#xff1a;从图中选取一点&#xff0c;求这个点到图中其他…

纯C++信号槽使用Demo (sigslot 库使用)

sigslot 库与QT的信号槽一样&#xff0c;通过发送信号&#xff0c;触发槽函数&#xff0c;信号槽不是QT的专利&#xff0c;早在2002年国外的一小哥用C写了sigslot 库&#xff0c;简单易用&#xff1b; 该库的官网&#xff08;喜欢阅读的小伙伴可以仔细研究&#xff09;&#xf…