精华内容
下载资源
问答
  • 1.分支限界法求解单源最短路径 2.C++源码+程序说明文档 3.源码带详细注释
  • 主要为大家详细介绍了java使用Dijkstra算法实现单源最短路径,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • ** The Bellman-Ford algorithm solves the single-source shortest-paths problem in the general case in which edge weights may be negative. ...import java.io.IOException; import java.util.Scanner; public...

    **

    The Bellman-Ford algorithm solves the single-source shortest-paths problem in the general case in which edge weights may be negative.

    **
    import java.io.IOException;
    import java.util.Scanner;

    public class Bellman_Ford {

    public class ENode2 {
    	int weight;
    	int ivex; // 该边所指向的顶点的位置
    	ENode2 nextEdge; // 指向下一条弧的指针
    }
    
    // 邻接表中表的顶点
    private class VNode2 {
    	int d;
    	VNode2 pre;
    	char data; // 顶点信息
    	ENode2 firstEdge; // 指向第一条依附该顶点的弧
    };
    
    private VNode2[] mVexs; // 顶点数组
    
    /*
     * 创建图(自己输入数据)
     */
    public Bellman_Ford() {
    
    	// 输入"顶点数"和"边数"
    	System.out.printf("input vertex number: ");
    	int vlen = readInt();
    	System.out.printf("input edge number: ");
    	int elen = readInt();
    	if (vlen < 1 || elen < 1 || (elen > (vlen * (vlen - 1)))) {
    		System.out.printf("input error: invalid parameters!\n");
    		return;
    	}
    
    	// 初始化"顶点"
    	mVexs = new VNode2[vlen];
    	for (int i = 0; i < mVexs.length; i++) {
    		System.out.printf("vertex(%d): ", i);
    		mVexs[i] = new VNode2();
    		mVexs[i].data = readChar();
    		mVexs[i].firstEdge = null;
    	}
    
    	// 初始化"边"
    	// mMatrix = new int[vlen][vlen];
    	for (int i = 0; i < elen; i++) {
    		// 读取边的起始顶点和结束顶点
    		System.out.printf("edge(%d):", i);
    		char c1 = readChar();
    		char c2 = readChar();
    		int w = readInt();
    		int p1 = getPosition(c1);
    		int p2 = getPosition(c2);
    		// 初始化node1
    		ENode2 node1 = new ENode2();
    		node1.ivex = p2;
    		node1.weight = w;
    		// 将node1链接到"p1所在链表的末尾"
    		if (mVexs[p1].firstEdge == null)
    			mVexs[p1].firstEdge = node1;
    		else
    			linkLast(mVexs[p1].firstEdge, node1);
    	}
    }
    
    public Bellman_Ford(char[] vexs, char[][] edges, int[] weigh) {
    
    	// 初始化"顶点数"和"边数"
    	int vlen = vexs.length;
    	int elen = edges.length;
    
    	// 初始化"顶点"
    	mVexs = new VNode2[vlen];
    	for (int i = 0; i < mVexs.length; i++) {
    		mVexs[i] = new VNode2();
    		mVexs[i].data = vexs[i];
    		mVexs[i].firstEdge = null;
    	}
    
    	// 初始化"边"
    	for (int i = 0; i < elen; i++) {
    		// 读取边的起始顶点和结束顶点
    		char c1 = edges[i][0];
    		char c2 = edges[i][1];
    		// 读取边的起始顶点和结束顶点
    		int p1 = getPosition(edges[i][0]);
    		int p2 = getPosition(edges[i][1]);
    
    		// 初始化node1
    		ENode2 node1 = new ENode2();
    		node1.ivex = p2;
    		// 将node1链接到"p1所在链表的末尾"
    		if (mVexs[p1].firstEdge == null)
    			mVexs[p1].firstEdge = node1;
    		else
    			linkLast(mVexs[p1].firstEdge, node1);
    		node1.weight = weigh[i];
    	}
    }
    
    public void Initialize() {
    	for (int i = 0; i < mVexs.length; i++) {
    		mVexs[i].d = Integer.MAX_VALUE;
    		// mVexs[i].pre = null;
    	}
    	mVexs[0].d = 0;
    }
    
    
    public boolean Bellman_Ford() {
    	Initialize();// 初始化
    	// System.out.println("输出最短路径:");
    	// System.out.printf("%c",mVexs[0].data );
    	for (int i = 0; i < mVexs.length; i++) {
    		for (int j = 0; j < mVexs.length; j++) {
    			ENode2 node = mVexs[j].firstEdge;
    			while (node != null) {
    				if (mVexs[node.ivex].d > mVexs[j].d + node.weight) {//进行relax操作
    					mVexs[node.ivex].d = mVexs[j].d + node.weight;
    				}
    				// Relax(mVexs[i], mVexs[node.ivex]);
    				node = node.nextEdge;
    			}
    		}
    	}
    	for (int k = 0; k < mVexs.length; k++) {
    		ENode2 node = mVexs[k].firstEdge;
    		while (node != null) {
    			if (mVexs[(node.ivex)].d > mVexs[k].d + node.weight) {
    				return false;
    			}
    			node = node.nextEdge;
    		}
    	}
    	
    	return true;
    	
    }
    
    //输出源点s到每个节点的最短路径
    public void Distance() {
    	System.out.print("输出源点s到每个节点的最短路径:");
    	for (int i = 0; i < mVexs.length; i++) {
    		System.out.print(mVexs[i].data+":"+mVexs[i].d+"   ");
    
    	}
    	System.out.println();
    }
    
    //输出最短路径
    public void SmallPath_output() {
    	boolean temp = Bellman_Ford();
    	if (temp == false) {
    		System.out.println("存在权重为负值的环路!");
    
    	} else {
    		System.out.println("输出最短路径为:");
    		for (int i = 0; i < mVexs.length; i++) {
    			ENode2 node = mVexs[i].firstEdge;
    			while (node != null) {
    				if (mVexs[(node.ivex)].d == mVexs[i].d + node.weight&&node.ivex==0) {
    					System.out.println("指向源节点的不输出!");
    				}
    				else if(mVexs[(node.ivex)].d == mVexs[i].d + node.weight){
    					System.out.println(mVexs[i].data + "-->" + mVexs[(node.ivex)].data + " " + node.weight);
    				}
    				node = node.nextEdge;
    			}
    		}
    
    	}
    
    }
    
    
    //输出每条边的权重
    public void PrintWeight() {
    	for (int i = 0; i < mVexs.length; i++) {
    		ENode2 node = mVexs[i].firstEdge;
    		while (node != null) {
    			System.out.println(mVexs[i].data+"-->"+mVexs[node.ivex].data+" "+node.weight);
    			node = node.nextEdge;
    		}
    	}
    }
    
    /*
     * 将node节点链接到list的最后
     */
    private void linkLast(ENode2 list, ENode2 node) {
    	ENode2 p = list;
    
    	while (p.nextEdge != null)
    		p = p.nextEdge;
    	p.nextEdge = node;
    }
    
    /*
     * 返回ch位置
     */
    private int getPosition(char ch) {
    	for (int i = 0; i < mVexs.length; i++)
    		if (mVexs[i].data == ch)
    			return i;
    	return -1;
    }
    
    /*
     * 读取一个输入字符
     */
    private char readChar() {
    	char ch = '0';
    
    	do {
    		try {
    			ch = (char) System.in.read();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	} while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));
    
    	return ch;
    }
    
    /*
     * 读取一个输入字符
     */
    private int readInt() {
    	Scanner scanner = new Scanner(System.in);
    	return scanner.nextInt();
    }
    
    /*
     * 打印矩阵队列图
     */
    public void Graph_Print() {
    	System.out.println("List Graph:");
    	for (int i = 0; i < mVexs.length; i++) {
    		System.out.print( i+"("+ mVexs[i].data+"):");
    		ENode2 node = mVexs[i].firstEdge;
    		while (node != null) {
    			System.out.print( node.ivex+"("+ mVexs[i].data+"-"+node.weight+"->"+ mVexs[node.ivex].data+")");
    			System.out.printf("\t");
    			node = node.nextEdge;
    		}
    		System.out.printf("\n");
    	}
    }
    
    public static void main(String[] args) {
    
    	int[] weight = { 6, 7, 5, 8, -4, -2, -3, 9, 2, 7 };
    	char[] vexs = { 'A', 'B', 'C', 'D', 'E' };
    	char[][] edges = new char[][] { { 'A', 'B' }, { 'A', 'D' }, { 'B', 'C' }, { 'B', 'D' }, { 'B', 'E' },
    			{ 'C', 'B' }, { 'D', 'C' }, { 'D', 'E' }, { 'E', 'A' }, { 'E', 'C' }, };
    
    	Bellman_Ford bf = new Bellman_Ford(vexs, edges, weight);
    	bf.PrintWeight();
    	bf.Graph_Print();
    	//bf.Bellman_Ford();
    	System.out.println(bf.Bellman_Ford());
    	bf.Distance();
    	bf.SmallPath_output();
    
    }
    

    }

    展开全文
  • - -可编辑修改 - 单源最短路径 计科 1 班 朱润华 2012040732 方法 1 贪心算法 一贪心算法解决单源最短路径问题描述 单源最短路径描述 给定带权有向图 G=(V,E, 其中每条边的权是非负实数 另外还给 定 V 中的一个顶点...
  • NULL 博文链接:https://128kj.iteye.com/blog/1678532
  • import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.... /** 单源最短路径问题 */ public class MinimumPath { /** 节点个数 */ pr...

    import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Scanner; /** 单源最短路径问题 */ public class MinimumPath { /** 节点个数 */ private int mapSize = 5; private int totalNum = 0; /** 组织节点间关系的二维数组 */ private int[][] map = null; /** 红点集合,记录已经被走过的顶点 */ private List redPoint = new ArrayList(); /** 蓝点集合,记录未走过的定点 */ private List bluePoint = new LinkedList(); public MinimumPath() { // 初始化由树转化成的二维数组 initiMap(); setMap(); // 初始化未走过的节点 for (int i = 0; i < mapSize; ++i) { bluePoint.add(i); } // 打印将数转换成的二维数组,按这个数组寻找最短路径 printMap(); } /** * 贪心算法递归求解最短路径 * @param startPoint:开始查找节点,下标从零开始 */ public void minStep(int startPoint) { // 如果输入不合法,则会退出 if (startPoint >= mapSize || startPoint < 0) { totalNum = Integer.MAX_VALUE; return; } // 将startPoint从为走过的节点去除,加入到走过的节点 redPoint.add(new Integer(startPoint)); bluePoint.remove(new Integer(startPoint)); // 如果完成则退出 if (startPoint == mapSize - 1) { return; } // 在未走过的节点中选择最短的路径 int temp = Integer.MAX_VALUE; int step = 0; Iterator iter = bluePoint.iterator(); for (int i = 0; i < bluePoint.size() && iter.hasNext(); ++i) { int j = iter.next(); if (temp > map[startPoint][j]) { temp = map[startPoint][j]; step = j; } } // 将最短路径加起来,并进入递归求解 totalNum += temp; minStep(step); } /** * 打印map */ private void printMap() { System.out.println("本程序以书上的节点为例, $代表无穷远"); for (int j = 0; j < mapSize; ++j) { for (int i = 0; i < mapSize; ++i) { if (map[j][i] == Integer.MAX_VALUE) { // $表示不能到达 System.out.print("$\t"); } else { System.out.print(map[j][i] + "\t"); } } System.out.println(); } } /** * 为map赋初值 */ private void setMap() { // 第零个节点和其他节点的距离,未赋值代表无穷远 map[0][0] = 0; map[0][1] = 10; map[0][3] = 30; map[0][4] = 100; // 第一个节点到其他节点的距离,未负值代表无穷远 map[1][1] = 0; map[1][2] = 50; // 第二个节点到其他节点的距离,未负值代表无穷远 map[2][2] = 0; map[2][4] = 10; // 第三个节点到其他节点的距离,未赋值代表无穷远 map[3][2] = 20; map[3][3] = 0; map[3][4] = 60; // 第四个节点到其他节点的距离,未赋值代表无穷远 map[4][4] = 0; } /** * 初始化map */ private void initiMap() { // 实例化并初始化map, Integer.MAX_VALUE表示不能到达 map = new int[mapSize][mapSize]; for (int j = 0; j < mapSize; ++j) { for (int i = 0; i < mapSize; ++i) { map[j][i] = Integer.MAX_VALUE; } } } public List getRedPoint() { return redPoint; } public int getTotalNum() { return totalNum; } public static void main(String[] args) { MinimumPath path = new MinimumPath(); System.out.println("请输入开始的节点(下表从零开始):"); // 获取输入节点, 比计算到达末节点的单源最短路径 Scanner sc = new Scanner(System.in); int v = sc.nextInt(); path.minStep(v); // 遍历路径 List red = path.getRedPoint(); for (Integer i : red) { System.out.print(i + " -> " + "\t"); } // 输出最短距离 int total = path.getTotalNum(); if(total != Integer.MAX_VALUE){ System.out.println("最短路径:" + total); } else { System.out.println("对不起,不能到达!"); } } }

    展开全文
  • java实现单源最短路径

    2020-08-26 10:27:16
    主要为大家详细介绍了java实现单源最短路径,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 这个问题通常称为单源最短路径问题. 输入: 第一行为一个整数n,表示包含源在内的顶点的个数,接下来是一个n*n的矩阵,矩阵中-1表示此路不通,否则表示从该顶点到另一顶点的距离。例如对于上图所示的问题我们可以按...
  • 算法设计与分析实验报告,附已通过源码,...1.问题描述 2.实验目的 3.实验原理 4.实验设计 (包括输入格式、算法、输出格式) 5.实验结果与分析 (除了截图外,实验结果还用图表进行了分析) 6.结论 7.程序源码
  • 分支限界法 (1)描述:采用广度优先产生状态空间树的结点,并使用剪枝函数的方法称为分枝限界法。 所谓“分支”是采用广度优先的策略,依次生成扩展结点的...重复上述结点扩展过程,直至找到问题的解或判定无解为止。
  • 一、单源最短路径问题 1、问题描述 在下图所给的有向图G中,每一边都有一个非负边权。要求图G的从源顶点s到目标顶点t之间的最短路径。 下图是用优先队列式分支限界法解有向图G的单源最短路径问题产生的解空间树。...

    转自:http://www.cnblogs.com/chinazhangjie/archive/2010/11/01/1866136.html

    分支限界法与回溯法

    (1)求解目标:回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。

    (2)搜索方式的不同:回溯法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树。

    分支限界法的基本思想

    分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。

    在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。

    此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。

    常见的两种分支限界法

    (1)队列式(FIFO)分支限界法

    按照队列先进先出(FIFO)原则选取下一个结点为扩展结点。

    (2)优先队列式分支限界法

    按照优先队列中规定的优先级选取优先级最高的结点成为当前扩展结点。

    一、单源最短路径问题

    1、问题描述

    在下图所给的有向图G中,每一边都有一个非负边权。要求图G的从源顶点s到目标顶点t之间的最短路径。

    21a3dc138afe836ff2dd8a33771015aa.png

    下图是用优先队列式分支限界法解有向图G的单源最短路径问题产生的解空间树。其中,每一个结点旁边的数字表示该结点所对应的当前路长。

    6baf800fe01f1b0bdf00081984131a6a.png

    找到一条路径:

    341fb2f92b079eb55652ba93293632e9.png

    目前的最短路径是8,一旦发现某个结点的下界不小于这个最短路进,则剪枝:

    cf537676d97ebb15b84a1fef4e02ff8a.png同一个结点选择最短的到达路径:

    b8b7d7edddcffbf7d9d6a7bbbffb9141.png

    60449c79140d2ea0f3d774eec1646cd2.png

    2.剪枝策略

    在算法扩展结点的过程中,一旦发现一个结点的下界不小于当前找到的最短路长,则算法剪去以该结点为根的子树。

    在算法中,利用结点间的控制关系进行剪枝。从源顶点s出发,2条不同路径到达图G的同一顶点。由于两条路径的路长不同,因此可以将路长长的路径所对应的树中的结点为根的子树剪去。

    3.算法思想

    解单源最短路径问题的优先队列式分支限界法用一极小堆来存储活结点表。其优先级是结点所对应的当前路长。

    算法从图G的源顶点s和空优先队列开始。结点s被扩展后,它的儿子结点被依次插入堆中。此后,算法从堆中取出具有最小当前路长的结点作为当前扩展结点,并依次检查与当前扩展结点相邻的所有顶点。如果从当前扩展结点i到顶点j有边可达,且从源出发,途经顶点i再到顶点j的所相应的路径的长度小于当前最优路径长度,则将该顶点作为活结点插入到活结点优先队列中。这个结点的扩展过程一直继续到活结点优先队列为空时为止。

    实现

    8f900a89c6347c561fdf2122f13be562.png

    961ddebeb323a10fe0623af514929fc1.png

    1 2.剪枝策略在算法扩展结点的过程中,一旦发现一个结点的下界不小于当前找到的最短路长,则算法剪去以该结点为根的子树。 在算法中,利用结点间的控制关系进行剪枝。从源顶点s出发,2条不同路径到达图G的同一顶点。由于两条路径的路长不同,因此可以将路长长的路径所对应的树中的结点为根的子树剪去。 3.算法思想解单源最短路径问题的优先队列式分支限界法用一极小堆来存储活结点表。其优先级是结点所对应的当前路长。算法从图G的源顶点s和空优先队列开始。结点s被扩展后,它的儿子结点被依次插入堆中。此后,算法从堆中取出具有最小当前路长的结点作为当前扩展结点,并依次检查与当前扩展结点相邻的所有顶点。如果从当前扩展结点i到顶点j有边可达,且从源出发,途经顶点i再到顶点j的所相应的路径的长度小于当前最优路径长度,则将该顶点作为活结点插入到活结点优先队列中。这个结点的扩展过程一直继续到活结点优先队列为空时为止。实现2 /*主题:单源最短路径问题3 * 作者:chinazhangjie4 * 邮箱:chinajiezhang@gmail.com5 * 开发语言:C++6 * 开发环境:Mircosoft Virsual Studio 20087 * 时间: 2010.11.018 */

    9

    10 #include

    11 #include

    12 #include

    13 #include

    14 using namespacestd;15

    16 structnode_info17 {18 public:19 node_info (int i,intw)20 : index (i), weight (w) {}21 node_info ()22 : index(0),weight(0) {}23 node_info (const node_info &ni)24 : index (ni.index), weight (ni.weight) {}25

    26 friend27 bool operator < (const node_info& lth,const node_info&rth) {28 return lth.weight > rth.weight ; //为了实现从小到大的顺序

    29 }30

    31 public:32 int index; //结点位置

    33 int weight; //权值

    34 };35

    36 structpath_info37 {38 public:39 path_info ()40 : front_index(0), weight (numeric_limits::max()) {}41

    42 public:43 intfront_index;44 intweight;45 };46

    47 //single source shortest paths

    48 classss_shortest_paths49 {50

    51 public:52 ss_shortest_paths (const vector >& g,intend_location)53 :no_edge (-1), end_node (end_location), node_count (g.size()) , graph (g)54 {}55

    56 //打印最短路径

    57 void print_spaths () const{58 cout << "min weight :" << shortest_path < (cout, " "));62 cout <

    65 //求最短路径

    66 voidshortest_paths () {67 vectorpath(node_count);68 priority_queue >min_heap;69 min_heap.push (node_info(0,0)); //将起始结点入队

    70

    71 while (true) {72 node_info top = min_heap.top (); //取出最大值

    73 min_heap.pop ();74

    75 //已到达目的结点

    76 if (top.index ==end_node) {77 break;78 }79 //未到达则遍历

    80 for (int i = 0; i < node_count; ++i) {81 //顶点top.index和i间有边,且此路径长小于原先从原点到i的路径长

    82 if (graph[top.index][i] != no_edge &&

    83 (top.weight + graph[top.index][i])

    94 shortest_path =path[end_node].weight;95 int index =end_node;96 s_path_index.push_back(index) ;97 while (true) {98 index =path[index].front_index ;99 s_path_index.push_back(index);100 if (index == 0) {101 break;102 }103 }104 }105

    106 private:107 vector > graph ; //图的数组表示

    108 int node_count; //结点个数

    109 const int no_edge; //无通路

    110 const int end_node; //目的结点

    111 vector s_path_index; //最短路径

    112 int shortest_path; //最短路径

    113 };114

    115 intmain()116 {117 const int size = 11;118 vector >graph (size);119 for (int i = 0;i < size; ++i) {120 graph[i].resize (size);121 }122 for (int i = 0;i < size; ++i) {123 for (int j = 0;j < size; ++j) {124 graph[i][j] = -1;125 }126 }127 graph[0][1] = 2;128 graph[0][2] = 3;129 graph[0][3] = 4;130 graph[1][2] = 3;131 graph[1][5] = 2;132 graph[1][4] = 7;133 graph[2][5] = 9;134 graph[2][6] = 2;135 graph[3][6] = 2;136 graph[4][7] = 3;137 graph[4][8] = 3;138 graph[5][6] = 1;139 graph[5][8] = 3;140 graph[6][9] = 1;141 graph[6][8] = 5;142 graph[7][10] = 3;143 graph[8][10] = 2;144 graph[9][8] = 2;145 graph[9][10] = 2;146

    147 ss_shortest_paths ssp (graph, 10);148 ssp.shortest_paths ();149 ssp.print_spaths ();150 return 0;151 }

    View Code

    测试数据(图)

    ba2cfea389ca2ab0851c01ca4dfe551b.png

    测试结果

    min weight : 8

    path: 0 2 6 9 10

    展开全文
  • java单源最短路径(贪心算法) public class TheShortestWay { static int MAX_SIZE = 6; public static void dijkstra(int v, float[][] a, float[] dist, int[] prev) { int n = dist.length - 1; if (v ||...
  • java算法分析与设计之单源最短路径(Dijkstra算法)源代码 算法作为计算机专业学生的必修课,同时也是软件开发过程中必备的编程思想,对学习研究计算机专业意义重大;正因为这门课程难,所以除了相关方面的书籍,网络...
  • 单源最短路径问题一、实验目的:二、实验内容及要求:三、实验原理:四、源代码 一、实验目的: 1、理解分支限界法的剪枝搜索策略; 2、掌握分支限界法的算法柜架; 3、掌握分支限界法的算法步骤; 4、通过应用范例...

    一、实验目的:

    1、理解分支限界法的剪枝搜索策略;
    2、掌握分支限界法的算法柜架;
    3、掌握分支限界法的算法步骤;
    4、通过应用范例学习动态规划算法的设计技巧与策略;

    二、实验内容及要求:

    1、使用分支限界法解决单源最短路径问题。
    2、通过上机实验进行算法实现。
    3、保存和打印出程序的运行结果,并结合程序进行分析,上交实验报告。

    三、实验原理:

    1.创建一个实现Comparable接口的节点类HeapNode,该类具有两个属性,分别是节点编号index和源点到该节点的最短距离length。同时在该类中重写compareTo方法,使用最短距离length属性作为比较条件,从小到大排序。

    2.函数shortest()开始创建一个LinkedList对象,元素类型为HeapNode类,由于其本质是一个双向链表且元素HeapNode类具有compareTo方法,因此可以充当优先级队列。将各顶点的最短距离赋值为Float.MAX_VALUE,完成初始化工作。While循环完成最短距离的更新工作,对于当前的扩展结点, 依次检查与之相邻的所有顶点。如果从源点经顶点node到顶点i的路径长度小于当前的最短距离,就更新顶点i的最短距离并将顶点node作为顶点i的前趋节点,将顶点i加入到链表对象中,重新进行链表排序,找到当前距离源点最近的顶点,最后取出链表中的头节点,实现扩展结点更新。当链表为空时,退出循环,得到最短距离。

    四、源代码

    import java.util.Collections;
    import java.util.LinkedList;
    import java.util.Scanner;
    
    public class ShortestPath {
        /**
         * 节点类
         */
        private static class HeapNode implements Comparable {
            // 当前节点的编号
            private int index;
            // 当前到达此节点的最短距离
            private float length;
    
            public HeapNode(int index,float length) {
                this.index = index;
                this.length = length;
            }
    
            /**
             * 重写compareTo方法,便于排序使用
             * @param object : 另一个节点
             * @return
             */
            @Override
            public int compareTo(Object object) {
                float len = ((HeapNode) object).length;
                return (length < len) ? 1:0;
            }
        }
    
        /**
         *  分支限界(单源最短路径)
         * @param a : 两点间的距离数组
         * @param dist : 当前最短距离数组
         * @param origin : 源点编号
         * @param prev : 前趋节点数组
         */
        public static void shortest(float[][] a,float[] dist,int origin,int[] prev) {
            // 顶点数量
            int n = prev.length - 1;
            // 创建节点链表
            LinkedList<HeapNode> nodes = new LinkedList<>();
            // 创建源节点
            HeapNode node = new HeapNode(origin,0);
            for (int i = 1;i <= n;++i) {
                // 初始化最短距离为Float.MAX_VALUE
                dist[i] = Float.MAX_VALUE;
            }
            while (true) {
                for (int i = 1;i <= n;++i) {
                    // 两节点间存在路径且到节点node的距离加两点间距离小于当前到节点i的最短距离
                    if (a[node.index][i] != -1 && node.length + a[node.index][i] < dist[i]) {
                        // 更新当前到节点i的最短距离
                        dist[i] = node.length + a[node.index][i];
                        // 更新节点i的前趋节点
                        prev[i] = node.index;
                        // 创建节点i对象
                        HeapNode heapNode = new HeapNode(i,dist[i]);
                        // 添加到链表中
                        nodes.add(heapNode);
                        // 按距离从短到长排序
                        Collections.sort(nodes);
                    }
                }
                // 链表为空退出循环
                if (nodes.isEmpty()) {
                    break;
                }else {
                    // 取出当前距离源点最近的节点
                    node = nodes.poll();
                }
            }
            // 输出结果
            for (int i = 2;i <= n;++i) {
                System.out.println(i+"节点的最短距离是:"+dist[i]+";前驱点是:"+prev[i]);
            }
        }
    
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            System.out.print("请输入图的顶点数:");
            // 创建顶点数量
            int n = in.nextInt();
            // 消除回车键影响
            in.nextLine();
            // 创建前趋节点数组
            int[] prev = new int[n+1];
            // 创建两点间距离数组
            float[][] a = new float[n+1][n+1];
            // 创建最短距离数组
            float[] dist = new float[n+1];
            System.out.println("请输入图的路径长度:");
            for (int i = 0;i < n;++i) {
                // 获得一行内容
                String line = in.nextLine();
                //将一个顶点到其他顶点的距离转成距离数组
                String[] length = line.split(",");
                for (int j = 0;j < length.length;++j) {
                    // 赋值
                    a[i+1][j+1] = Float.parseFloat(length[j]);
                }
            }
            // 调用最短路径算法
            shortest(a,dist,1,prev);
            in.close();
        }
    }
    
    展开全文
  • 单源最短路径径 此版本为Java题解版 这是一道模板题,对于单源最短路径的题,我们首选Dijikstra算法。 首先我们对算法思路进行一个复习。 暴力解法(思路清晰,适合入门) 建立dis数组,用于记录单源最短路径。 ...
  • cout求最短路径 voidshortest_paths () { vectorpath(node_count); priority_queue >min_heap; min_heap.push (node_info(0,0)); //将起始结点入队 while (true) { node_info top= min_heap.top (); //取出最大值 ...
  • 采用java编写的单源路径分支界面法,参考:算法设计与分析
  • "2020-11-18 20:30:09","createByName":"pWX619094","createByAccount":"pWX619094","createAt":"2020-11-18 20:30:09","contentCheckCode":0},{"id":"8000-000000560298-0","keyword":"docker文件存放路径, 获取...
  • 单源最短路径问题java实现(分支限界法)具体问题描述以及C/C++实现参见网址http://blog.csdn.net/liufeng_king/article/details/8900872import java.util.Collections;import java.util.LinkedList;import java....
  • 用C++实现的贪心算法 Dijkstra 单源最短路径,并包含大量的注释,对理解程序很有帮助
  • #Dijkstra 算法 使用 van emde boas 树在 O(Vloglog(V) + Aloglog(V)) 中运行的 Dijkstra 算法。 使用二进制堆以 O(A log(V)) 运行的 Dijkstra 算法。
  • java单源最短路径算法

    2021-03-11 15:09:30
    单源最短路径的 Dijkstra 算法: 问题描述: 给定一...并 应用贪心法求解单源最短路径问题。环境要求对于环境没有特别要求。对于算法实现,可以自由选择 C, C++, Java,甚至于其他程序 设计语言。实验步骤步骤 1:理解.....
  • 这个问题通常称为单源最短路径问题。dijkstra算法简介迪杰斯特拉算法(Dijkstra),是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心...
  • 单源最短路径问题: import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.Scanner; /** * * @author 刘宁宁 */ public class BBShortest { static float[]...
  • 贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就 是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。 贪心算法思路: 建立数学模型来描述问题; 把求解的问题分成若干...
  • 给定一个带权有向图 G=(V,E) ,其中每条边的权是一个整数。另外,还给定 V 中的一个顶点,称为源。现在我们要计算从源到所有其他各顶点的最短路径长度。这里的长度是指路上各边权...这个问题通常称为单源最短路径问题
  • 单源最短路径问题

    2020-06-23 16:43:35
    本篇只考虑无权图的最短路径问题一:走迷宫问题 方案一(dfs + 回溯): 方案二(bfs): 问题二:单词接龙(leetcode127) 解法一(dfs + 回溯): 解法二(bfs获得最短路径): 问题一:走迷宫问题 ...
  • 基于贪心算法求解单源最短路径问题 算法描述 给定带权有向图G=(V,E)G=(V,E)G=(V,E),其中每条边的权都是非负实数。另外,还给定VVV中的一个顶点,称为源。现在要计算从源到所有其他各个顶点的最短路径长度。这里路劲...
  • 单源最短路径问题问题提出是,计算带权有向图G =(V, E)中一个点(源点)到其余各顶点的最短路径长度,如下图所示。设源点为顶点1,采用Dijkstra算法求下图中源V0为到其余各顶点的最短路径。 直接上代码吧: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,613
精华内容 1,045
关键字:

单源最短路径问题java

java 订阅