数据结构实验6:图的应用
目录
一、实验目的
1. 邻接矩阵
2. 邻接矩阵表示图的结构定义
3. 图的初始化
4. 边的添加
5. 边的删除
6. Dijkstra算法
三、实验内容
实验内容
代码
截图
分析
一、实验目的
1.掌握图的邻接矩阵的存储定义;
2.掌握图的最短路径(Dijsktra)算法的实现。
二、实验原理
1. 邻接矩阵
邻接矩阵是一种表示图的方法。它是一个二维数组,用于表示图中各个顶点之间的连接关系。如果图是有向图,那么邻接矩阵是对称的;如果是无向图,邻接矩阵可能不是对称的。
顶点的编号: 假设图有n个顶点,通常是从1到n。
构建矩阵: 创建一个n x n的矩阵,其中元素a[i][j]表示顶点i到顶点j是否有边。如果存在边,通常用1表示;如果不存在边,通常用0表示。
例如,对于无向图,如果顶点i和顶点j之间有边,则a[i][j]和a[j][i]都设置为1。对于有向图,只需设置a[i][j]为1表示从顶点i到顶点j有一条有向边。
权重: 如果图中的边有权重,可以在矩阵中存储这些权重。矩阵的元素a[i][j]可以表示从顶点i到顶点j的权重值。
2. 邻接矩阵表示图的结构定义
#define MAX_SIZE 100struct Graph {int numVertices;//节点数int adjMatrix[MAX_SIZE][MAX_SIZE];//邻接矩阵
};
3. 图的初始化
创建一个空的图数据结构并为其设置初始状态。
void InitializeGraph(struct Graph* graph,int num) {int i, j;graph->numVertices = num;for (i = 0; i < num; i++) {for (j = 0; j < num; j++) {graph->adjMatrix[i][j] = 0;}}
}
4. 边的添加
在图中增加边,将该边置为1,表示存在,或者权值
若是无向图,由于对称性,则需要改变两条边
//添加边
void addEdge(struct Graph* graph, int startVertex, int endVertex) {graph->adjMatrix[startVertex][endVertex] = 1;//若是无向图graph->adjMatrix[endVertex][startVertex] = 1;
}
5. 边的删除
置为0(不存在)或者无限大的权值
void deleteEdge(struct Graph* graph, int startVertex, int endVertex) {graph->adjMatrix[startVertex][endVertex] = 0;//若是无向图graph->adjMatrix[endVertex][startVertex] = 0;
}
6. Dijkstra算法
Dijkstra算法是一种用于在带有非负权重的图中找到单源最短路径的算法。该算法的基本思想是从起始顶点开始,逐步扩展到离起始顶点的距离最短的顶点,直到到达目标顶点为止。
初始化: 对于每个顶点v,初始化距离值dist[v]为无穷大(表示尚未到达该顶点),并将起始顶点的距离值dist[start]设置为0。创建一个优先队列(最小堆),将起始顶点加入队列。
更新距离值: 从优先队列中取出距离值最小的顶点u。对于u的每个邻接顶点v,如果通过u可以缩短到达v的距离(dist[start] + weight(u, v) < dist[v]),则更新dist[v]的值。更新后,将v加入优先队列。
重复步骤2: 重复上述步骤,直到优先队列为空。这样,对于每个顶点,dist数组中存储的值就是从起始顶点到达该顶点的最短路径距离。
Dijkstra算法的关键在于通过贪心策略,每次选择距离起始顶点最近的顶点进行扩展。这确保了每个顶点的最短路径被逐步确定,直到到达目标顶点
//Dijkstra算法
void dijkstra(struct Graph* graph, int startVertex) {int dist[MAX_SIZE]; // 存储从起始节点到各节点的最短距离int visited[MAX_SIZE] = { 0 }; // 标记节点是否被访问过// 初始化距离数组for (int i = 0; i < graph->numVertices; i++) {dist[i] = INT_MAX;}// 起始节点到自身的距离为0dist[startVertex] = 0;for (int count = 0; count < graph->numVertices - 1; count++) {int minDist = 9999;int minIndex;// 选择距离最小的未访问节点for (int v = 0; v < graph->numVertices; v++) {if (!visited[v] && dist[v] < minDist) {minDist = dist[v];//当前最短距离minIndex = v;//当前最短的点}}// 标记节点为已访问visited[minIndex] = 1;// 更新最短距离数组//!visited[v]:检查节点 v 是否已经被访问过,如果节点已经被访问过,则不需要更新最短距离。//graph->adjacencyMatrix[minIndex][v] != 9999:检查从当前节点 minIndex 到节点 v 是否存在边。9999 表示两个节点之间没有直接的连接,因此如果这个条件为真,说明节点 minIndex 和节点 v 之间存在边。// dist[minIndex] != 9999:检查起始节点到节点 minIndex 的最短距离是否已经被初始化,如果没有被初始化,说明当前节点 minIndex 不可达,无法通过它来更新其他节点的距离。//(dist[minIndex] + graph->adjMatrix[minIndex][v] < dist[v]):检查通过当前节点 minIndex 更新节点 v 的距离是否比已知的最短距离 dist[v] 更短。如果是,就更新 dist[v] 为更短的距离。for (int v = 0; v < graph->numVertices; v++) {if (!visited[v] && graph->adjMatrix[minIndex][v] != 9999 && dist[minIndex] != 9999 && (dist[minIndex] + graph->adjMatrix[minIndex][v] < dist[v])) {dist[v] = dist[minIndex] + graph->adjMatrix[minIndex][v];}}}// 打印最短距离cout<<"从"<< startVertex<<"节点为起点"<<endl;for (int i = 0; i < graph->numVertices; i++) {cout<<"到"<<i<<"节点的最短距离为:" << dist[i]<<endl;}
}
三、实验内容
实验内容
必做内容:
设计安徽大学的校园平面图,所含景点不少于 8 个。以图中顶点表示学校内各景点,存放景点的名称、景点介绍信息等;以边表示路径,存放路径长度信息。要求将这些信息保存在文件 graph.txt 中,系统执行时所处理的数据要对此文件分别进行读写操作。
1.从文件 graph.txt 中读取相应数据, 创建一个图,使用邻接矩阵表示图;
2.景点信息查询:为来访客人提供校园任意景点相关信息的介绍;
3.问路查询:为来访客人提供校园任意两个景点之间的一条最短路径;
选做内容(对文件进行操作,相应信息变化后,再次进行景点信息查询和
问路查询时应该有所体现):
1. 修改一个已有景点的相关信息;
2. 增加一个新景点及其相关信息;
3. 增加一条新的路径;
4. 删除一个景点及其相关信息;
5. 删除一条路径。
代码
#define _CRT_SECURE_NO_WARNINGS
#include<fstream>
#include<iostream>
using namespace std;#define MAX_SIZE 100struct Graph {int numVertices;//节点数int adjMatrix[MAX_SIZE][MAX_SIZE];//邻接矩阵,用来储存距离char address[MAX_SIZE][MAX_SIZE];//景点名称char intro[MAX_SIZE][MAX_SIZE];//景点介绍
};//图的初始化
void InitializeGraph(struct Graph* graph,int num) {int i, j;graph->numVertices = num;for (i = 0; i < num; i++) {for (j = 0; j < num; j++) {graph->adjMatrix[i][j] = 9999;}}
}//添加边
void addEdge(struct Graph* graph, int startVertex, int endVertex,int length) {graph->adjMatrix[startVertex][endVertex] = length;//若是无向图graph->adjMatrix[endVertex][startVertex] = length;
}//删除边
void deleteEdge(struct Graph* graph, int startVertex, int endVertex) {graph->adjMatrix[startVertex][endVertex] = 0;//若是无向图graph->adjMatrix[endVertex][startVertex] = 0;
}//找到编号对应的景点名称
void find_address(struct Graph* graph, int index) {cout << graph->address[index];
}//Dijkstra算法
void dijkstra(struct Graph* graph, int startVertex, int endVertex) {int visited[MAX_SIZE] = { 0 };//记录是否被访问过int pre[MAX_SIZE] = { startVertex };//记录前驱点编号int min_leng[MAX_SIZE];for (int i = 0; i < MAX_SIZE; i++) {min_leng[i] = 9999;}visited[startVertex] = 1;int min_length = 9999;int min_index = startVertex;//第一轮for (int j = 0; j < graph->numVertices; j++) {if (visited[j] == 0) {//如果未被访问过//cout << graph->adjMatrix[startVertex][j] << " " << min_leng[j] << endl;if (graph->adjMatrix[startVertex][j] < min_leng[j]) {//如果新的起始点到达终点的距离更短,则前驱节点为新的起始点//find_address(graph, j);pre[j] = startVertex;min_leng[j] = graph->adjMatrix[startVertex][j] ;}}//cout << endl;for (int j = 0; j < graph->numVertices; j++) {//找最短路径作为新一轮的起始点if (visited[j] == 0) {//如果未被访问过if (min_leng[j] < min_length) {min_length = min_leng[j];min_index = j;}}}visited[min_index] = 1;}for (int i = 0; i < graph->numVertices - 2; i++) {//共顶点数-2轮 for (int j = 0; j < graph->numVertices; j++) {if (visited[j] == 0) {//如果未被访问过//cout <<graph-> adjMatrix[min_index][j]<<" " << min_leng[j] << endl;if ((graph->adjMatrix[min_index][j] + min_length) < min_leng[j]) {//如果新的起始点到达终点的距离更短,则前驱节点为新的起始点//find_address(graph, j);pre[j] = min_index;min_leng[j] = graph->adjMatrix[min_index][j] + min_length;}}//cout << endl;}//cout << "更新一轮"<<endl;for (int j = 0; j < graph->numVertices; j++) {//cout << min_leng[j] << " ";}min_length = 9999;min_index = startVertex;for (int j = 0; j < graph->numVertices; j++) {//找最短路径作为新一轮的起始点if (visited[j] == 0) {//如果未被访问过if (min_leng[j] < min_length) {min_length = min_leng[j];min_index = j;}}}visited[min_index] = 1;//cout << "这一轮起始点为";//find_address(graph, min_index);// cout << endl << "到达起始点距离为" << min_length << endl;}cout <<"最短距离为:"<< min_leng[endVertex]<<endl;//输出最短路径,从后往前找前驱cout << "最短路径为:";int count = 2;int road[MAX_SIZE] ;for (int i = 0; i < MAX_SIZE; i++) {road[i] = endVertex;}road[0] = startVertex;int end = endVertex;//尾while (pre[end] != startVertex) {//计算路径中的景点数count++;end = pre[end];}end = endVertex;for (int i = count - 2; i >= 0; i--) {road[i] = pre[end];end = pre[end];}int flag = 1;for (int i = 0; i < count; i++) {if (flag == 0) {cout << "->";}find_address(graph, road[i]);flag = 0;}return;
}//找到该景点对应的编号
int find_index(struct Graph* graph, char string[]) {for (int i = 0; i < graph->numVertices; i++) {if (strcmp(string, graph->address[i]) == 0) {return i;}}cout << "不存在该景点" << endl;return -1;
}//景点信息查询
void volun1(struct Graph* graph) {cout << "本校景点有:" << endl;for (int i = 0; i < graph->numVertices; i++) {cout <<i<<":"<< graph->address[i] << endl;}char string1[MAX_SIZE];cout << "请输入你要查询的景点:";cin >> string1;int index = find_index(graph, string1);cout << graph->intro[index] << endl;
}//最短路径查询
void volun2(struct Graph* graph) {char source[MAX_SIZE], destination[MAX_SIZE];cout << "请输入起始景点和目的景点:";cin >> source >> destination;int start = 0, end = 0;start = find_index(graph, source);end = find_index(graph, destination);dijkstra(graph, start, end);cout << endl;
}//增加景点相关信息
void volun3(struct Graph* graph) {char address[MAX_SIZE], intro[MAX_SIZE];cout << "请输入你要增加的景点名称及其相关信息:"<<endl;cin >> address >> intro;//将信息复制进去strcpy(graph->address[graph->numVertices], address);strcpy(graph->intro[graph->numVertices], intro);graph->numVertices++;//修改节点数//相关路径全改为无穷大for (int i = 0; i < graph->numVertices; i++) {graph->adjMatrix[i][graph->numVertices - 1] = 9999;}for (int i = 0; i < graph->numVertices; i++) {graph->adjMatrix[graph->numVertices - 1][i] = 9999;}
}//修改景点的相关信息
void volun4(struct Graph* graph) {char address[MAX_SIZE], intro[MAX_SIZE];cout << "请输入你要修改的景点名称及其相关信息:" << endl;cin >> address >> intro;//找到编号int des_index = find_index(graph, address);//修改memset(graph->intro[des_index], MAX_SIZE, sizeof(char));//清空strcpy(graph->intro[des_index], intro);
}//增加路径
void volun5(struct Graph* graph) {char source[MAX_SIZE], destination[MAX_SIZE]; int length;cout << "请输入你要增加的路径:" << endl;cin >> source >> destination >> length;int start = find_index(graph, source);int end = find_index(graph, destination);addEdge(graph, start, end, length);
}//删除一个景点及其相关信息
void volun6(struct Graph* graph) {char address[MAX_SIZE];cout << "请输入你要删除的景点:" << endl;cin >> address;int index = find_index(graph, address);//清空memset(graph->address[index], MAX_SIZE, sizeof(char));memset(graph->intro[index], MAX_SIZE, sizeof(char));
}//删除一条路径
void volun7(struct Graph* graph) {char source[MAX_SIZE], destination[MAX_SIZE];cout << "请输入你要删除的路径:" << endl;cin >> source >> destination;int start = find_index(graph, source);int end = find_index(graph, destination);deleteEdge(graph, start, end);
}int main() {struct Graph q;int num_V, num_a;//顶点数目,边的个数FILE* filePointer;filePointer = fopen("C:\\Users\\Administrator\\Desktop\\graph.txt", "r");// 检查文件是否成功打开if (filePointer == NULL) {cout << "无法打开文件";return 1; // 退出程序}char buffer[1000];char Address[MAX_SIZE], Intro[MAX_SIZE];// 读取一行数据if (fgets(buffer, sizeof(buffer), filePointer) != NULL) {if (sscanf(buffer, "%d %d", &num_V, &num_a) == 2) {q.numVertices = num_V;//cout << num_V << " " << num_a<<endl;}else {cout<<"错误:无法从字符串中提取两个数字。" << endl;}} else {cout<<"错误:文件为空或无法读取。" << endl;}InitializeGraph(&q, num_V);//初始化图//读取景点名称及其介绍for (int i = 0; i < num_V; i++) {if (fgets(buffer, sizeof(buffer), filePointer) != NULL) {if (sscanf(buffer, "%s %s", Address, Intro) == 2) {strcpy(q.address[i], Address);strcpy(q.intro[i], Intro);//cout << q.address[i] << endl;//cout << q.intro[i] << endl;}else {printf("错误:无法从字符串中提取两个字符串。\n");}}else {cout << "错误:文件为空或无法读取。" << endl;}}//读取景点之间距离char source[MAX_SIZE], destination[MAX_SIZE];int length=0;for (int i = 0; i < num_a; i++) {if (fgets(buffer, sizeof(buffer), filePointer) != NULL) {if (sscanf(buffer, "%s %s %d", source, destination,&length) == 3) {int index1 = find_index(&q, source);int index2 = find_index(&q, destination);q.adjMatrix[index1][index2] = length;q.adjMatrix[index2][index1] = length;//cout << index1 << " " << index2 << " " << length << endl;}else {cout<<"错误:无法从字符串中提取两个字符串,一个数字。"<<endl;}}else {cout << "错误:文件为空或无法读取。" << endl;}}// 关闭文件fclose(filePointer);//信息填充完毕,接下来是查阅环节int code;cout << "********************欢迎来到安徽大学!********************" << endl;cout << " 1.查询景点信息" << endl;cout << " 2.问路查询" << endl;cout << " 3.增加一个景点及其相关信息" << endl;cout << " 4.修改一个景点的相关信息" << endl;cout << " 5.增加一个新的路径" << endl;cout << " 6.删除一个景点及其相关信息" << endl;cout << " 7.删除一条路径" << endl;cout << " 8.退出" << endl;cout << "********************安大校园导游系统*********************" << endl;cout << "请选择需要的服务:(1-8)" << endl;cin >> code;while (code != 8) {switch (code){case 1: volun1(&q); break;case 2: volun2(&q); break;case 3: volun3(&q); break;case 4: volun4(&q); break;case 5: volun5(&q); break;case 6: volun6(&q); break;case 7: volun7(&q); break;}cin >> code;}cout << "退出" << endl;return 0;
}
截图


分析
对于上述代码,是存在一个问题的,比如增加一个节点,删除俩个节点,总数目减少,但是最大索引值是在增加的,所以再次实现其他功能的时候是不切实际的
way1:提供一个有效位数组,按最大索引值的范围查找
way2: 当删除时,后面的节点索引值应该加以改变,但是很麻烦
此外上述代码提到了sscanf函数
sscanf函数接受一个字符串作为输入,并根据指定的格式从该字符串中读取数据,然后将数据存储在相应的变量中。#include <stdio.h>int sscanf(const char *str, const char *format, ...);
str是包含格式化数据的输入字符串。format是描述输入字符串中数据格式的格式字符串。- 可变参数(
...)是用于存储从输入字符串中读取的数据的变量列表。
相关文章:
数据结构实验6:图的应用
目录 一、实验目的 1. 邻接矩阵 2. 邻接矩阵表示图的结构定义 3. 图的初始化 4. 边的添加 5. 边的删除 6. Dijkstra算法 三、实验内容 实验内容 代码 截图 分析 一、实验目的 1.掌握图的邻接矩阵的存储定义; 2.掌握图的最短路径…...
Spring Boot整合JUnit
引言 测试是软件开发过程中不可或缺的一环,而JUnit作为Java生态中最流行的测试框架之一,与Spring Boot的整合为开发者提供了一套强大的测试工具。本文将讨论Spring Boot整合JUnit的技术细节、最佳实践以及测试驱动开发(TDD)的优雅…...
uniapp写小程序实现清除缓存(存储/获取/移除/清空)
在uni-app中,可以使用uni.setStorageSync和uni.getStorageSync来进行数据的存储和获取。而移除缓存数据可以使用uni.removeStorageSync,清空缓存数据可以使用uni.clearStorageSync。 以下是使用示例: 存储数据: uni.setStorage…...
js菜单隐藏显示
1、树状结构对应的表: 2、生成menulist的SQL语句 select {"id":"MenuID","parent":"ParentID","FirstLvMenu":"FirstLvMenu", "text":"MenuName","url":"MenuUrl",&quo…...
学习Spring的第五天(Bean的依赖注入)
Bean的依赖注入有两种方式: 一 . 常规Bean的依赖注入 很简单,不过多赘述了,注意ref: 是构造函数或set方法的参数,一般为对象, value: 是构造函数或set方法的参数,一般为值. 看下图 1.1 下面来演示一下集合数据类型的关于Bean的依赖注入 1.1.1这是List的注入(演示泛型为Strin…...
GAN在图像数据增强中的应用
在图像数据增强领域,生成对抗网络(GAN)的应用主要集中在通过生成新的图像数据来扩展现有数据集的规模和多样性。这种方法特别适用于训练数据有限的情况,可以通过增加数据的多样性来提高机器学习模型的性能和泛化能力。 以下是GAN在…...
Git推送本地文件到仓库
1. 在 Gitee 上创建一个新的仓库: 登录到 Gitee(https://gitee.com)账号。在 Gitee 主页上选择 "新建仓库" 或类似选项。输入仓库名称和描述,并选择其他相关选项(如公开/私有)。确认创建仓库 …...
Django笔记(一):环境部署
目录 Python虚拟环境 安装virtualenv 创建环境 激活环境 关闭: 安装Django VSCode配置 Python插件 Django插件 解释器选择 Django部署 创建项目 创建app 创建模板 编写视图 编写路由 启动服务器 访问 Python虚拟环境 安装virtualenv pip i…...
用Pytorch实现线性回归模型
目录 回顾Pytorch实现步骤1. 准备数据2. 设计模型class LinearModel代码 3. 构造损失函数和优化器4. 训练过程5. 输出和测试完整代码 练习 回顾 前面已经学习过线性模型相关的内容,实现线性模型的过程并没有使用到Pytorch。 这节课主要是利用Pytorch实现线性模型。…...
WordPress模板层次与常用模板函数
首页: home.php index.php 文章页: single-{post_type}.php – 如果文章类型是videos(即视频),WordPress就会去查找single-videos.php(WordPress 3.0及以上版本支持) single.php index.php 页面: 自定义模板 – 在WordPre…...
HarmonyOS应用开发者高级认证试题库(鸿蒙)
目录 考试链接: 流程: 选择: 判断 单选 多选 考试链接: 华为开发者学堂华为开发者学堂https://developer.huawei.com/consumer/cn/training/dev-certification/a617e0d3bc144624864a04edb951f6c4 流程: 先进行…...
系分备考计算机网络传输介质、通信方式和交换方式
文章目录 1、概述2、传输介质3、网络通信4、网络交换5、总结 1、概述 计算机网路是系统分析师考试的常考知识点,本篇主要记录了知识点:网络传输介质、网络通信和数据交换方式等。 2、传输介质 网络的传输最常见的就是网线,也就是双绞线&…...
js原生面试总结
冒泡循环 var arr[2,1,3,4,9,7,6,8] // 外层循环代表循环次数 内层循环时每次的两两对比 少一次循环 for (let i 0; i < arr.length-1; i) {// 如果进入判断代表当前值大于下一个是需要进行冒泡排序的let booltruefor (let j 0; j < arr.length-1-i; j) {// 虽然…...
接口自动化测试框架设计
文章目录 接口测试的定义接口测试的意义接口测试的测试用例设计接口测试的测试用例设计方法postman主要功能请求体分类JSON数据类型postman内置参数postman变量全局变量环境变量 postman断言JSON提取器正则表达式提取器Cookie提取器postman加密接口签名 接口自动化测试基础getp…...
详解ISIS动态路由协议
华子目录 前言应用场景历史起源ISIS路由计算过程ISIS的地址结构ISIS路由器分类ISIS邻居关系的建立P2PMA ISIS中的DIS与OSPF中DR的对比链路状态信息的交互ISIS的最短路径优先算法(SPF)ISIS区域划分ISIS区域间路由访问原理ISIS与OSPF的不同ISIS与OSPF的术语…...
Linux操作系统----gdb调试工具(配实操图)
绪论 “不用滞留采花保存,只管往前走去,一路上百花自会盛开。 ——泰戈尔”。本章是Linux工具篇的最后一章。gdb调试工具是我们日常工作中需要掌握的一项重要技能我们需要基本的掌握release和debug的区别以及gdb的调试方法的指令。下一章我们将进入真正…...
去除GIT某个时间之前的提交日志
背景 有时git提交了太多有些较早之前的提交日志,不想在git log看到,想把他删除掉。 方法 大概思路是通过 git clone --depth 来克隆到指定提交的代码,此时再早之前的日志是没有的 然后提交到新仓库 #!/bin/bash ori_git"gityour.gi…...
4 python快速上手
计算机常识知识 1.Python代码运行方式2.进制2.1 进制转换 3. 计算机中的单位4.编码4.1 ascii编码4.2 gb-2312编码4.3 unicode4.4 utf-8编码4.5 Python相关的编码 总结 各位小伙伴想要博客相关资料的话关注公众号:chuanyeTry即可领取相关资料! 1.Python代…...
单元测试-spring-boot-starter-test+junit5
前言: 开发过程中经常需要写单元测试,记录一下单元测试spring-boot-starter-testjunit5的使用 引入内容: 引用jar包 <!-- SpringBoot测试类依赖 --> <dependency><groupId>org.springframework.boot</groupId><…...
CentOS 7上安装Anaconda 详细教程
目录 1. 下载Anaconda安装脚本2. 校验数据完整性(可选)3. 运行安装脚本4. 遵循安装指南5. 选择安装位置6. 初始化Anaconda7. 激活安装8. 测试安装9. 更新Anaconda10. 使用Anaconda 1. 下载Anaconda安装脚本 首先需要从Anaconda的官方网站下载最新的Anac…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
