`
shenyu
  • 浏览: 123430 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

图-代权最小树

阅读更多

图中代权的最小树的问题如下:


如果N个城市之间(图中的顶点)要修公路(图中的边)以使所有的城市联通,求怎样修可以使得公路的总长最小?
以上问题中的N个城市之间可以用图中的顶点表示,公路可以图中的边表示,公路的长度用边长表示,公路是双向的。问题就转换为在有N个顶点中的双向代权图中求得一个最小树。这里的代权指的边的长度,这与以前的不代权的最小树生成算法有很大的区别。


算法描述如下:


    任选一个节点开始,将该节点标志为已访问过的节点。也就是最小树中的节点。并设置为当前节点。
    1 寻找此访问节点的所有的邻接顶点,将边置入优先队列。邻接顶点不考虑已标志为访问的节点,因为它已在结果中。
    2 重复 步骤1 直到没有新的边被发现。此时在所有发现的边中找到最小的边,将其终点顶点标志为已访问,放入最小树中。并设置为当前节点
    3 重复 步骤 1,2,直到边的队列中没有多余的边,算法结束。

    注意:这里的优先级队列是个修正过的优先级队列,每次向该队列中加入一条新边时后,会检查是否有与新边终点相同的第二条边的存在,如果有,则删除边长较大的边。因为如果存在这样的边说明,有两条从已访问过节点到相同目标节点的路径存在,如果这样的话只用保留最小的那条边即可。

这里的图采用Graph 图-邻接矩阵法 表示。



算法实际上是作如下操作:


    先准备好一个优先级队列,里面以边长为关键值存放边,边的起点表示已被访问过的节点,而边的终点表示未访问的节点。将某节点标志为访问过节点。开始算法。
    寻找该访问过节点的所有边,并记录边长,放入边优先级队列中;
    找到所有从已访问过的节点到未访问节点的边中的最小边;
    将最小边连接的顶点设置为访问过,重复以上过程,直到所有节点都变成已访问。

主要的类如下:

    Edge:记载边

    PriorityQ:修正后的优先级队列

    Vertex:顶点

    Gragh:图

        Gragh.mstw():最小树生成算法

        Gragh.main():提供简单测试

代码如下:

class Edge {	//边:记载起始,与终止节点的下标,以及边的长度
	private int from;
	private int to;
	private int length;
	Edge(int from, int to, int length) {
		this.from = from;
		this.to = to;
		this.length = length;
	}

	int from() { return from; }	//起点
	int to() { return to; }	//终点
	int length() { return length; }	//边长
}

/**
 * 修正过的优先级队列,边长最小的队列的头部,且队列中不会出现到达同一个节点
 * 的两条边,如果添加新边到队列中时出现这种情况,则队列自动删除边长较大的边。
 */
class PriorityQ {	
	private Edge[] edges;
	private int pos = -1;
	PriorityQ(int size) {	//创建指定长度的优先级队列
		edges = new Edge[size];
	}

	void add(Edge edge) {	//添加新边到队列中
		assert pos < edges.length;
		//按照边长将新边插入队列中合适的位置
		int index = ++pos;
		while(index > 0 && edges[index-1].length() < edge.length()) {
			edges[index] = edges[index-1];
			index--;	
		}
		edges[index] = edge;	

		//在队列中检查是否有与新边终点相同的边,如果有则作修正处理
		removeDuplicate(edge.to());		
	}

	private void removeDuplicate(int to) {	//根据终点在队列中查找重复的边,并处理
		int count = 0;	//记录找到同样终点的边的个数
		for(int index=pos; index>-1; index--) {
			if(edges[index].to() == to) count++;	
			if(count == 2) {	//将第二次找到的边作删除处理
				for(int i=index; i<pos; i++) edges[i] = edges[i+1];
				pos--;
				return;
			}
		}
	}

	Edge remove() {	//移出并返回最小的边
		return edges[pos--];	
	}

	boolean isEmpty() { return pos == -1; }
}

class Vertex {	//顶点类,记载顶点的value,并可以记录是否访问过
	private Object value;
	private boolean isVisited;
	Vertex(Object value) {
		this.value = value;
	}

	void visit() { isVisited = true; }
	void clean() {	isVisited = false; }
	boolean isVisited() { return isVisited; }
	Object value() { return value; }
	@Override public String toString() { return "" + value; }
}

class Graph {	//无向图,记录顶点,顶点之间的边,以及边的长度
	private Vertex[] vertexs;
	private int[][] adjMat;
	private int length = 0;
	private static final int INFINITY = -1;	//表示不存在边时的状态

	Graph(int size) {	//初始化图的数据结构,包括顶点,边,边都置为不存在
		vertexs = new Vertex[size];	
		adjMat = new int[size][size];
		for(int i=0; i<size; i++) 
			for(int j=0; j<size; j++)
				adjMat[i][j] = INFINITY;
	}

	void add(Object value) {	//添加新的顶点
		assert length <= vertexs.length;
		vertexs[length++] = new Vertex(value);
	}

	void connect(int from, int to, int length) {	//顶点之间添加边,指定边长
		adjMat[from][to] = length;
		adjMat[to][from] = length;
	}

	/**
	 * 在邻接矩阵中,查找指定顶点的未访问过邻居顶点
	 * 如果从从起点到终点的边存在,且没有标志为访问,则返回终点下标。
	 * @param offset 指定开始查找的列
	 * @param index	指定查找的行
	 */
	int findNeighbor(int index,int offset) {	//
		for(int i=offset; i<length; i++) {
			if(adjMat[index][i] != INFINITY && !vertexs[i].isVisited()) return i;
		}
		return -1;
	}

	Edge[] mstw(int index) {	//最小树生成算法,index为开始的坐标
		assert vertexs[index] != null;
		Edge[] result = new Edge[length-1]; //生成结果数组,边的数量为顶点数量-1
		PriorityQ q = new PriorityQ(length);	//准备优先级队列
		int pos = -1;
		vertexs[index].visit();	//将起始顶点标志为访问过的
		while(true) {
			//寻找已访问过的节点与未访问过节点之间的边,并加入优先级队列
			int i = -1;
			while((i = findNeighbor(index,i+1)) != -1) {	
				Edge e = new Edge(index,i,adjMat[index][i]);
				q.add(e);	
			}
			if(q.isEmpty()) break;	//如果队列中没有多余的边,算法结束
			
			//在队列中找到边长最短的边,将终点节点标志为访问过,并将此边从队列中删除
			result[++pos] = q.remove();	
			index = result[pos].to();	//以新的终点作为起点,准备下一次迭代
			vertexs[index].visit();
		}
		clean();	//将所有访问标志复位
		return result;
	}

	void clean() { for(Vertex v: vertexs) if(v != null)v.clean(); }

	Object get(int index) { return vertexs[index]; }

	public static void main(String[] args) {	//测试
		Graph g = new Graph(20);
		//添加顶点
		g.add('a');
		g.add('b');
		g.add('c');
		g.add('d');
		g.add('e');
		g.add('f');
		//连接顶点,并指明边长
		g.connect(0,1,6);
		g.connect(0,3,4);
		g.connect(1,2,10);
		g.connect(1,3,7);
		g.connect(1,4,7);
		g.connect(2,3,8);
		g.connect(2,4,5);
		g.connect(2,5,6);
		g.connect(3,4,12);
		g.connect(4,5,7);
		int sum = 0;	//记录总边长
		for(Edge e: g.mstw(4)) {	//以任意顶点开始生成最小树
			System.out.println(g.get(e.from()) + " -- " + g.get(e.to()) + " : " + e.length());
			sum += e.length();
		}
		System.out.println(sum);
	}
}
 

 

7
2
分享到:
评论
3 楼 abo 2008-05-28  


如果所有的边的端点必须是顶点(城市),这样的公路网络只会在偶然的情况下是总长度最小的。
2 楼 woailuo 2008-05-28  
正好在复习,看看!
1 楼 yxgd 2008-05-27  
喜欢!辛苦了.

相关推荐

    p3_collab-compet

    因此,每个特工的目标是保持比赛中的球权。 观察空间由8个变量组成,分别对应于球和球拍的位置和速度。 每个代理都会收到自己的本地观察结果。 有两个连续的动作可用,分别对应于朝向(或远离)网络的运动和跳跃。...

    responsive-pulse:ROS出版社

    严格的层次结构,不灵活的矩阵报告结构,会议丰富的时间表以及仅适用于最长任期的成员的决策权–这些“功能”阻止了任何实际工作的完成。 我们一直在研究以新方式工作的小组,因此,与竞争对手相比,它们对世界的...

    实时监控体系:基于Prometheus的API性能指标可视化方案.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    5个提升DeepSeekAPI生成质量的调参技巧,开发者必看!.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    ACM动态规划模板-区间修改线段树问题模板

    ACM动态规划模板-区间修改线段树问题模板

    深度解析C语言调试技巧:VSCode+GDB实战排错指南.pdf

    # 踏入C语言的奇妙编程世界 在编程的广阔宇宙中,C语言宛如一颗璀璨恒星,以其独特魅力与强大功能,始终占据着不可替代的地位。无论你是编程小白,还是有一定基础想进一步提升的开发者,C语言都值得深入探索。 C语言的高效性与可移植性令人瞩目。它能直接操控硬件,执行速度快,是系统软件、嵌入式开发的首选。同时,代码可在不同操作系统和硬件平台间轻松移植,极大节省开发成本。 学习C语言,能让你深入理解计算机底层原理,培养逻辑思维和问题解决能力。掌握C语言后,再学习其他编程语言也会事半功倍。 现在,让我们一起开启C语言学习之旅。这里有丰富教程、实用案例、详细代码解析,助你逐步掌握C语言核心知识和编程技巧。别再犹豫,加入我们,在C语言的海洋中尽情遨游,挖掘无限可能,为未来的编程之路打下坚实基础!

    10个高效调用DeepSeekAPI的技巧:从请求优化到缓存策略.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    基于Python语言的PersonRelationKnowledgeGraph设计源码

    本项目为Python语言开发的PersonRelationKnowledgeGraph设计源码,总计包含49个文件,涵盖19个.pyc字节码文件、12个.py源代码文件、8个.txt文本文件、3个.xml配置文件、3个.png图片文件、2个.md标记文件、1个.iml项目配置文件、1个.cfg配置文件。该源码库旨在构建一个用于表示和查询人物关系的知识图谱系统。

    成本优化指南:通过Token计算模型将API费用降低57%的秘诀.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    大华智能物联平台,的对接其他接口的API,可以获得视频拉流的flv/hls/rstp 的拉流地址,demo项目为springBoot项目,可以通过摄像头的视频通道,获取到实时拉流的uRl

    rtsp实时预览接口URL:/evo-apigw/admin/API/MTS/Video/StartVideo HLS、FLV、RTMP实时预览接口方式 :接口URL/evo-apigw/admin/API/video/stream/realtime 参数名 必选 类型 说明 data true string Json串 +channelId true string 视频通道编码 +streamType true string 码流类型:1=主码流, 2=辅码流,3=辅码流2 +type true string 协议类型:hls,hlss,flv,flvs,ws_flv,wss_flv,rtmp hls:http协议,m3u8格式,端口7086; hlss:https协议,m3u8格式,端口是7096; flv:http协议,flv格式,端口7886; flvs:https协议,flv格式,端口是7896; ws_flv:ws协议,flv格式,端口是7886; wss_flv:wss协议,flv格式,端口是7896; rtmp:rtmp协议,端口是1975;

    Simulink永磁风机飞轮储能系统二次调频技术研究:频率特性分析与参数优化,Simulink永磁风机飞轮储能二次调频技术:系统频率特性详解及参数优化研究参考详实文献及两区域系统应用,simulink

    Simulink永磁风机飞轮储能系统二次调频技术研究:频率特性分析与参数优化,Simulink永磁风机飞轮储能二次调频技术:系统频率特性详解及参数优化研究参考详实文献及两区域系统应用,simulink永磁风机飞轮储能二次调频,系统频率特性如下,可改变调频参数改善频率。 参考文献详细,两区域系统二次调频。 ,核心关键词: 1. Simulink 2. 永磁风机 3. 飞轮储能 4. 二次调频 5. 系统频率特性 6. 调频参数 7. 改善频率 8. 参考文献 9. 两区域系统 以上关键词用分号(;)分隔,结果为:Simulink;永磁风机;飞轮储能;二次调频;系统频率特性;调频参数;改善频率;参考文献;两区域系统。,基于Simulink的永磁风机与飞轮储能系统二次调频研究:频率特性及调频参数优化

    MATLAB驱动的ASR防滑转模型:PID与对照控制算法对比,冰雪路面条件下滑移率与车速轮速对照展示,MATLAB驱动的ASR防滑转模型:PID与对照控制算法对比,冰雪路面条件下滑移率与车速轮速对照图

    MATLAB驱动的ASR防滑转模型:PID与对照控制算法对比,冰雪路面条件下滑移率与车速轮速对照展示,MATLAB驱动的ASR防滑转模型:PID与对照控制算法对比,冰雪路面条件下滑移率与车速轮速对照图展示,MATLAB驱动防滑转模型ASR模型 ASR模型驱动防滑转模型 ?牵引力控制系统模型 选择PID控制算法以及对照控制算法,共两种控制算法,可进行选择。 选择冰路面以及雪路面,共两种路面条件,可进行选择。 控制目标为滑移率0.2,出图显示车速以及轮速对照,出图显示车辆轮胎滑移率。 模型简单,仅供参考。 ,MATLAB; ASR模型; 防滑转模型; 牵引力控制系统模型; PID控制算法; 对照控制算法; 冰路面; 雪路面; 控制目标; 滑移率; 车速; 轮速。,MATLAB驱动的ASR模型:PID与对照算法在冰雪路面的滑移率控制研究

    芯片失效分析方法介绍 -深入解析芯片故障原因及预防措施.pptx

    芯片失效分析方法介绍 -深入解析芯片故障原因及预防措施.pptx

    4131_127989170.html

    4131_127989170.html

    PostgreSQL自动化部署与优化脚本:智能化安装、安全加固与监控集成

    内容概要:本文提供了一个全面的PostgreSQL自动化部署解决方案,涵盖智能环境适应、多平台支持、内存与性能优化以及安全性加强等重要方面。首先介绍了脚本的功能及其调用方法,随后详细阐述了操作系统和依赖软件包的准备过程、配置项的自动生成机制,还包括对实例的安全性和监控功能的强化措施。部署指南给出了具体的命令操作指导,便于新手理解和执行。最后强调了该工具对于不同硬件条件和服务需求的有效应对能力,特别是针对云计算环境下应用的支持特点。 适合人群:对PostgreSQL集群运维有一定基础并渴望提高效率和安全性的数据库管理员及工程师。 使用场景及目标:本脚本能够帮助企业在大规模部署时减少人工介入时间,确保系统的稳定性与高性能,适用于各类需要稳定可靠的数据库解决方案的企业或机构,特别是在大数据量和高并发事务处理场合。 其他说明:文中还提及了一些高级功能如自动备份、流复制等设置步骤,使得该方案不仅可以快速上线而且能满足后续维护和发展阶段的要求。同时提到的技术性能数据也为用户评估其能否满足业务需求提供了直观参考。

    房地产开发合同[示范文本].doc

    房地产开发合同[示范文本].doc

    成本优化实战:DeepSeekAPI的Tokens计算与计费策略拆解.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    安全必读:DeepSeek接口调用中的数据加密与合规实践.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    工程技术承包合同[示范文本].doc

    工程技术承包合同[示范文本].doc

    蓝桥杯开发赛作品源码【基于C语言】

    蓝桥杯开发赛【作品源码】

Global site tag (gtag.js) - Google Analytics