import java.util.ArrayList;
import java.util.List;
// 模块E
public class AdjMatrixGraph<E> {
protected SeqList<E> vertexlist; // 顺序表存储图的顶点集合
protected int[][] adjmatrix; // 图的邻接矩阵 二维图 存储的是每个顶点的名称(A,B,C,D....)
private final int MAX_WEIGHT = Integer.MAX_VALUE / 2;
// private final int MAX_WEIGHT = 10000;
// -------一,构造图:增删改查-------------------------//
public AdjMatrixGraph(int n) {// n为顶点的数目
this.vertexlist = new SeqList<E>(n);
this.adjmatrix = new int[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
this.adjmatrix[i][j] = (i == j) ? 0 : MAX_WEIGHT;
// 对角线上为0,其他的都为无穷大。
}
// 构造函数内一个是字符串数组,一个是edge的set集合
public AdjMatrixGraph(E[] vertices, Edge[] edges) {
this(vertices.length);
for (int i = 0; i < vertices.length; i++)
insertVertex(vertices[i]);// 添加顶点
for (int j = 0; j < edges.length; j++)
insertEdge(edges[j]);// 添加边
}
// 构造函数内一个是数组集合,一个是edge的set集合
public AdjMatrixGraph(SeqList<E> list, Edge[] edges) {
this(list.length());
this.vertexlist = list;
for (int j = 0; j < edges.length; j++)
insertEdge(edges[j]);
}
// 显示出一共顶点的数目
public int vertexCount() {
return this.vertexlist.length();
}
// 根据编号得到该顶点
public E get(int i) {
return this.vertexlist.get(i);
}
public boolean insertVertex(E vertex) { // 插入一个顶点,若插入成功,返回true
return this.vertexlist.add(vertex);
}
public boolean insertEdge(int i, int j, int weight)
// 插入一条权值为weight的边<vi,vj>,若该边已有,则不插入
{
if (i >= 0 && i < vertexCount() && j >= 0 && j < vertexCount()
&& i != j && adjmatrix[i][j] == MAX_WEIGHT) {
// 先判断该边两个顶点的编号是否在范围,该边的值是否为最大值,来确定所添加边的值是否存在;
this.adjmatrix[i][j] = weight;// 添加权值
return true;
}
return false;
}
public boolean insertEdge(Edge edge) {
if (edge != null)
;
return insertEdge(edge.start, edge.dest, edge.weight);
}
public String toString() {
String str = "顶点集合: " + vertexlist.toString() + "\n";
str += "邻近矩阵: \n";
int n = vertexCount();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (adjmatrix[i][j] == MAX_WEIGHT)
str += " ∞";// 最大值(不存在)的时候的显示方式;
else
str += " " + adjmatrix[i][j];// 每一个顶点到其他顶点的权值
}
str += "\n";
}
return str;
}
public boolean removeEdge(int i, int j) // 删除边〈vi,vj〉,若成功,返回T
{
if (i >= 0 && i < vertexCount() && j >= 0 && j < vertexCount()
&& i != j && this.adjmatrix[i][j] != MAX_WEIGHT) {
// 判断该边的两个顶点是否存在,以及改边的值是否为最大值来判断改边是否存在;
this.adjmatrix[i][j] = MAX_WEIGHT; // 设置该边的权值为无穷大,说明已不存在;
return true;
}
return false;
}
public boolean removeVertex(int v) // 删除序号为v的顶点及其关联的边
{
int n = vertexCount(); // 删除之前的顶点数
if (v >= 0 && v < n) {// V的要求范围
this.vertexlist.remove(v); // 删除顺序表的第i个元素,顶点数已减一
for (int i = v; i < n - 1; i++)
for (int j = 0; j < n; j++)
this.adjmatrix[i][j] = this.adjmatrix[i + 1][j]; // 邻接矩阵:删除点以下往上移动一位
for (int j = v; j < n - 1; j++)
for (int i = 0; i < n - 1; i++)
this.adjmatrix[i][j] = this.adjmatrix[i][j + 1]; // 邻接矩阵:删除点以右往左移动一位
return true;
}
return false;
}
public int getFirstNeighbor(int v) // 返回顶点v的第一个邻接顶点的序号
{
return getNextNeighbor(v, -1);
} // 若不存在第一个邻接顶点,则返回-1
public int getNextNeighbor(int v, int w) { // 返回v在w后的下一个邻接顶点
if (v >= 0 && v < vertexCount() && w >= -1 && w < vertexCount()// 对v
// w的范围限定
&& v != w)
for (int j = w + 1; j < vertexCount(); j++)
// w=-1时,j从0开始寻找下一个邻接顶点
if (adjmatrix[v][j] > 0 && adjmatrix[v][j] < MAX_WEIGHT)
// 遍历和v相关的点,得到下一个点
return j;
return -1;
}
// -------二,最小生成树-------------------------//
/*
* 普里姆算法的基本思想: 取图中任意一个顶点 v 作为生成树的根,之后往生成树上添加新的顶点 w。 在添加的顶点 w
* 和已经在生成树上的顶点v之间必定存在一条边, 并且该边的权值在所有连通顶点 v 和 w 之间的边中取值最小。
* 之后继续往生成树上添加顶点,直至生成树上含有 n-1 个顶点为止。
*/
public AdjMatrixGraph minSpanTree_prim() {
Edge[] mst = new Edge[this.vertexCount() - 1]; // n个顶点最小生成树有n-1条边
int un;
List<Integer> u = new ArrayList<Integer>();// 存放所有已访问过的顶点集合
u.add(0);// 起始点默认为标识为0的顶点
for (int i = 0; i < this.vertexCount() - 1; i++) {
int minweight = MAX_WEIGHT;// 最小边的时候,权值
int minstart = MAX_WEIGHT;// 最小边的时候,起点
int mindest = MAX_WEIGHT;// 最小边的时候,终点
for (int j = 0; j < u.size(); j++) {
un = u.get(j);
for (int k = 0; k < this.vertexCount(); k++) {
// 获取最小值的条件:1.该边比当前情况下的最小值小;2.该边还未访问过;
if ((minweight > adjmatrix[un][k]) && (!u.contains(k))) {
minweight = adjmatrix[un][k];
minstart = un;
mindest = k;
}
}
}
System.out.println("一次遍历所添加的最小边:他的权值,起点,终点分别为:weight:" + minweight
+ "start:" + minstart + "dest:" + mindest);
u.add(mindest);
Edge e = new Edge(minstart, mindest, adjmatrix[minstart][mindest]);
mst[i] = e;
}
return new AdjMatrixGraph(this.vertexlist, mst); // 构造最小生成树相应的图对象
}
/*
* public AdjMatrixGraph minSpanTree_kruskal() { }
*/
// -------三,图的遍历(广度遍历,深度遍历)-------------------------//
public void DFStraverse() {
int n = this.vertexCount();
boolean[] visited = new boolean[n];
for (int i = 1; i < n; i++) {
visited[i] = false;
}
// 编号0为起始点,进行一次深度优先遍历(一次得到一个连通分量)
for (int j = 0; j < n; j++) {
if (!visited[j]) {
System.out.println("以该顶点为" + j + "起始点的遍历:");
this.DFS(j, visited);
}
}
}
// 参数1:遍历起始点的编号,参数2:记录各个顶点是否被访问过
public void DFS(int v, boolean[] visited2) {
boolean[] visited = visited2;
visited[v] = true;
System.out.println("遍历顶点" + v);
for (int w = this.getFirstNeighbor(v); w >= 0; w = this
.getNextNeighbor(v, w)) {
if (!visited[w]) {
visited[w] = true;
DFS(w, visited);
}
}
}
public void BFStraverse() {
int n = this.vertexCount();
boolean[] visited = new boolean[n];
MyQueue myqueue = new MyQueue();
for (int i = 1; i < n; i++) {
visited[i] = false;
}
for (int j = 0; j < n; j++) {
if (!visited[j]) {
visited[j] = true;
System.out.println("遍历起点:" + j);
myqueue.EnQueue(j);
while (!myqueue.empty()) {
int v = (Integer) myqueue.DeQueue();
System.out.println("遍历点:" + v);
for (int w = this.getFirstNeighbor(v); w >= 0; w = this
.getNextNeighbor(v, w)) {
if (!visited[w]) {
visited[w] = true;
myqueue.EnQueue(w);
}
}
}
}
}
}
// -------四,图的最短路径Dijkstra算法-------------------------//
public void Dijkstra() {
int n = this.vertexCount();
int minweight = MAX_WEIGHT;
int minUn = 0;
int[] minmatrix = new int[n];// 存放当前起始点到其余各个顶点的距离;
boolean[] isS = new boolean[n];// 判断各个是否被访问过
String[] route = new String[n];// 每个字符串是显示对应顶点最短距离的路径;
for (int i = 1; i < n; i++) {// 初始化
minmatrix[i] = adjmatrix[0][i];
isS[i] = false;
route[i] = "起点->" + i;
}
for (int i = 1; i < n; i++) {
// 选择 当前 和起点 连通的,且值最小的顶点;
for (int k = 1; k < n; k++) {
if (!isS[k]) {
if (minmatrix[k] < minweight) {
minweight = minmatrix[k];
minUn = k;
}
}
}
isS[minUn] = true;// 将该点设置为已访问;
for (int j = 1; j < n; j++) {
if (!isS[j]) {// 判断:该顶点还没加入到S中/属于U-S;
if (minweight + adjmatrix[minUn][j] < minmatrix[j]) {
// 通过当下最小值 访问到得其他顶点的距离小于原先的最小值 则进行交换值
minmatrix[j] = minweight + adjmatrix[minUn][j];
route[j] = route[minUn] + "->" + j;
}
}
}
minweight = MAX_WEIGHT;// 因为要放到下一个循环中,所以一定要重设置一下,回到最大值
}
for (int m = 1; m < n; m++) {
System.out.println("从V0出发到达" + m + "点");
if (minmatrix[m] == MAX_WEIGHT) {
System.out.println("没有到达该点的路径");
} else {
System.out.println("当前从V0出发到达该点的最短距离:" + minmatrix[m]);
System.out.println("当前从V0出发到达该点的最短距离:" + route[m]);
}
}
}
// -------五,图的连通性-------------------------//
public boolean isConnect() {
int n = this.vertexCount();
boolean[] visited = new boolean[n];
// 记录不能一次深度优先遍历通过的数目
// 全部顶点作为出发点开始遍历,如果全部都不能一次遍历通过(notConnectNum == n),说明该图不连通。
int notConnectNum = 0;
for (int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
visited[i] = false;
}
this.DFS(j, visited);
for (int k = 0; k < n; k++) {
System.out.println(visited[k]);
if (visited[k] == false) {
notConnectNum++;
break;// 一旦有没有被遍历到的顶点(说明该顶点不属于该连通分量),跳出循环
}
}
}
if (notConnectNum == n) {
System.out.println("此图是不连通的");
return false;
} else {
System.out.println("此图是连通的");
return true;
}
}
// -------六,图的拓扑排序-------------------------//
public void topologicalSort() {
int n = this.vertexCount();
int[] indegree = new int[n];
MyStack mystack = new MyStack();
String route = "拓扑排序出发:";
int count = 0;
for (int i = 0; i < n; i++) {
indegree[i] = 0;
for (int j = 0; j < n; j++) {//获取每一个顶点的入度
if (adjmatrix[j][i] != 0 && adjmatrix[j][i] != MAX_WEIGHT) {
indegree[i] += 1;
}
}//先将入度为0的顶点加入到栈中
if (indegree[i] == 0) {
mystack.push(i);
}
}
while (!mystack.empty()) {
int v = (Integer) mystack.pop();//从栈中删除该顶点
route += "->" + v;
++count;
for (int w = this.getFirstNeighbor(v); w >= 0; w = this
.getNextNeighbor(v, w)) {
indegree[w] -= 1;//因为该顶点被“删除”,所有以该顶点为弧尾的边的弧头的入度减一
if (indegree[w] == 0) {
mystack.push(w);//先将入度为0的顶点加入到栈中
}
}
}
if (count < n) {//当经历拓扑排序遍历后,所有顶点都被“删除”时(count=n),此时实现拓扑排序
System.out.println("存在回路,不满足拓扑排序的条件");
} else {
System.out.println("实现拓扑排序" + route);
}
}
}
分享到:
相关推荐
1、文件内容:ibus-table-chinese-erbi-1.4.6-3.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/ibus-table-chinese-erbi-1.4.6-3.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
选择Java后台技术和MySQL数据库,在前台界面为提升用户体验,使用Jquery、Ajax、CSS等技术进行布局。 系统包括两类用户:学生、管理员。 学生用户只要实现了前台信息的查看,打开首页,查看网站介绍、自习室信息、在线留言、轮播图信息公告等,通过点击首页的菜单跳转到对应的功能页面菜单,包括网站首页、自习室信息、注册登录、个人中心、后台登录。 学生用户通过账户账号登录,登录后具有所有的操作权限,如果没有登录,不能在线预约。学生用户退出系统将注销个人的登录信息。 管理员通过后台的登录页面,选择管理员权限后进行登录,管理员的权限包括轮播公告管理、老师学生信息管理和信息审核管理,管理员管理后点击退出,注销登录信息。 管理员用户具有在线交流的管理,自习室信息管理、自习室预约管理。 在线交流是对前台用户留言内容进行管理,删除留言信息,查看留言信息。
面向基层就业个性化大学生服务平台(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计 【功能需求】 面向基层就业个性化大学生服务平台(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计 面向基层就业个性化大学生服务平台中的管理员角色主要负责了如下功能操作。 (1)职业分类管理功能需求:对职业进行划分分类管理等。 (2)用户管理功能需求:对用户信息进行维护管理等。 (3)职业信息管理功能需求:对职业信息进行发布等。 (4)问卷信息管理功能需求:可以发布学生的问卷调查操作。 (5)个性化测试管理功能需求:可以发布个性化测试试题。 (6)试题管理功能需求:对测试试题进行增删改查操作。 (7)社区交流管理功能需求:对用户的交流论坛信息进行维护管理。 面向基层就业个性化大学生服务平台中的用户角色主要负责了如下功能操作。 (1)注册登录功能需求:没有账号的用户,可以输入账号,密码,昵称,邮箱等信息进行注册操作,注册后可以输入账号和密码进行登录。 (2)职业信息功能需求:用户可以对职业信息进行查看。 (3)问卷信息功能需求:可以在线进行问卷调查答卷操作。 (4)社区交流功能需求:可以在线进行社区交流。 (5)个性化测试功能需求:可以在线进行个性化测试。 (6)公告资讯功能需求:可以查看浏览系统发布的公告资讯信息。 【环境需要】 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.数据库:MySql 5.7/8.0等版本均可; 【购买须知】 本源码项目经过严格的调试,项目已确保无误,可直接用于课程实训或毕业设计提交。里面都有配套的运行环境软件,讲解视频,部署视频教程,一应俱全,可以自己按照教程导入运行。附有论文参考,使学习者能够快速掌握系统设计和实现的核心技术。
三菱Fx3u程序:自动检测包装机电机控制模板,PLC脉冲与伺服定位,手自动切换功能,三菱Fx3u程序:自动检测包装机电机控制模板——涵盖伺服定位与手自动切换功能,三菱Fx3u程序,自动检测包装机。 该程序六个电机,plc本体脉冲控制3个轴,3个1pg控制。 程序内包括伺服定位,手自动切,功能快的使用,可作为模板程序,很适合新手。 ,三菱Fx3u程序; 自动检测包装机; 六个电机; PLC脉冲控制; 伺服定位; 手自动切换; 功能快捷键; 模板程序。,三菱Fx3u PLC控制下的自动包装机程序:六电机伺服定位与手自动切换模板程序
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
计及信息间隙决策与多能转换的综合能源系统优化调度模型:实现碳经济最大化与源荷不确定性考量,基于信息间隙决策与多能转换的综合能源系统优化调度模型:源荷不确定性下的高效碳经济调度策略,计及信息间隙决策及多能转的综合能源系统优化调度 本代码构建了含风电、光伏、光热发电系统、燃气轮机、燃气锅炉、电锅炉、储气、储电、储碳、碳捕集装置的综合能源系统优化调度模型,并考虑P2G装置与碳捕集装置联合运行,从而实现碳经济的最大化,最重要的是本文引入了信息间隙决策理论考虑了源荷的不确定性(本代码的重点)与店铺的47代码形成鲜明的对比,注意擦亮眼睛,认准原创,该代码非常适合修改创新,,提供相关的模型资料 ,计及信息间隙决策; 综合能源系统; 优化调度; 多能转换; 碳经济最大化; 风电; 光伏; 燃气轮机; 储气; 储电; 储碳; 碳捕集装置; P2G装置联合运行; 模型资料,综合能源系统优化调度模型:基于信息间隙决策和多能转换的原创方案
IPG QCW激光模块电源驱动电路设计与实现:包含安全回路、紧急放电回路及光纤互锁功能的多版本原理图解析,IPG QCW激光模块电源驱动电路设计与实现:含安全回路、紧急放电及光纤互锁等多重保护功能的原理图解析,IPG QCW激光模块电源驱动电路, 包含安全回路,紧急放电回路,光纤互锁回路等, 元件参数请根据实际设计适当调整,此电路仅供参考,不提供pcb文件 原理图提供PDF和KICAD两个版本。 ,IPG激光模块; QCW激光电源驱动; 安全回路; 紧急放电回路; 光纤互锁回路; 原理图PDF和KICAD版本。,IPG激光模块电源驱动电路图解:含安全与紧急放电回路
基于LSSVM的短期电力负荷预测模型及其性能评估:结果揭露精确度与误差分析,LSSVM在短期电力负荷预测中的结果分析:基于均方根误差、平均绝对误差及平均相对百分误差的评估。,LSSVM最小二乘支持向量机做短期电力负荷预测。 结果分析 均方根误差(RMSE):0.79172 平均绝对误差(MAE):0.4871 平均相对百分误差(MAPE):13.079% ,LSSVM(最小二乘支持向量机);短期电力负荷预测;均方根误差(RMSE);平均绝对误差(MAE);平均相对百分误差(MAPE),LSSVM在电力负荷短期预测中的应用及性能分析
1、文件内容:libmtp-examples-1.1.14-1.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/libmtp-examples-1.1.14-1.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
资源内项目源码是均来自个人的课程设计、毕业设计或者具体项目,代码都测试ok,都是运行成功后才上传资源,答辩评审绝对信服的,拿来就能用。放心下载使用!源码、说明、论文、数据集一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 4、如有侵权请私信博主,感谢支持
2023-04-06-项目笔记-第四百一十六阶段-课前小分享_小分享1.坚持提交gitee 小分享2.作业中提交代码 小分享3.写代码注意代码风格 4.3.1变量的使用 4.4变量的作用域与生命周期 4.4.1局部变量的作用域 4.4.2全局变量的作用域 4.4.2.1全局变量的作用域_1 4.4.2.414局变量的作用域_414- 2025-02-21
MINIST数据集和春风机器学习框架
1、文件内容:ibus-table-chinese-wu-1.4.6-3.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/ibus-table-chinese-wu-1.4.6-3.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
宿舍管理系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计 【功能需求】 系统拥有管理员和学生两个角色,主要具备系统首页、个人中心、学生管理、宿舍信息管理、宿舍分配管理、水电费管理、进入宿舍管理、出入宿舍管理、维修信息管理、卫生信息管理、考勤信息管理、留言板、交流论坛、系统管理等功能模块。 【环境需要】 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.数据库:MySql 5.7/8.0等版本均可; 【购买须知】 本源码项目经过严格的调试,项目已确保无误,可直接用于课程实训或毕业设计提交。里面都有配套的运行环境软件,讲解视频,部署视频教程,一应俱全,可以自己按照教程导入运行。附有论文参考,使学习者能够快速掌握系统设计和实现的核心技术。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
人凤飞飞凤飞飞是粉色丰富
2024蓝桥杯嵌入式学习资料
image_download_1740129191509.jpg
基于Multisim仿真的带优先病房呼叫系统设计(仿真图) 设计一个病房呼叫系统。 功能 (1)当有病人紧急呼叫时,产生声,光提示,并显示病人的编号; (2)根据病人的病情设计优先级别,当有多人呼叫时,病情严重者优先; (3)医护人员处理完当前最高级别的呼叫后,系统按优先级别显示其他呼叫病人的病号。
基于STM32F103的3.6kW全桥逆变器资料:并网充电放电、智能切换与全方位保护方案,基于STM32F103的3.6kW全桥逆变器资料:并网充电放电、智能控制与全方位保护方案,逆变器光伏逆变器,3.6kw储能逆变器全套资料 STM32储能逆变器 BOOST 全桥 基于STM32F103设计,具有并网充电、放电;并网离网自动切;485通讯,在线升级;风扇智能控制,提供过流、过压、短路、过温等全方位保护。 基于arm的方案区别于dsp。 有PCB、原理图及代码ad文件。 ,逆变器; 储能逆变器; STM32F103; 3.6kw; 485通讯; 全方位保护; 智能控制; 方案区别; PCB文件; 原理图文件; ad文件。,基于STM32F103的3.6kw储能逆变器:全方位保护与智能控制