Day 38

一、学习内容

Dijkstra算法是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。

学习链接:(1条消息) Dijkstra算法(迪杰斯特拉算法)_持之以恒2016-CSDN博客

Prim 算法,图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。

学习链接:Prim算法(~详细整理,简单易懂,附最详细注释代码)_pursuit的博客-CSDN博客_prim算法

package datastructure.graph;

import java.util.Arrays;

import matrix.IntMatrix;

/**
 * Weighted graphs are called nets.
 * 
 * @author Fan Min minfanphd@163.com.
 */
public class Net {

	/**
	 * The maximal distance. Do not use Integer.MAX_VALUE.
	 */
	public static final int MAX_DISTANCE = 10000;

	/**
	 * The number of nodes.
	 */
	int numNodes;

	/**
	 * The weight matrix. We use int to represent weight for simplicity.
	 */
	IntMatrix weightMatrix;

	/**
	 *********************
	 * The first constructor.
	 * 
	 * @param paraNumNodes
	 *            The number of nodes in the graph.
	 *********************
	 */
	public Net(int paraNumNodes) {
		numNodes = paraNumNodes;
		weightMatrix = new IntMatrix(numNodes, numNodes);
		for (int i = 0; i < numNodes; i++) {
			// For better readability, you may need to write fill() in class
			// IntMatrix.
			Arrays.fill(weightMatrix.getData()[i], MAX_DISTANCE);
		} // Of for
	}// Of the first constructor

	/**
	 *********************
	 * The second constructor.
	 * 
	 * @param paraMatrix
	 *            The data matrix.
	 *********************
	 */
	public Net(int[][] paraMatrix) {
		weightMatrix = new IntMatrix(paraMatrix);
		numNodes = weightMatrix.getRows();
	}// Of the second constructor

	/**
	 *********************
	 * Overrides the method claimed in Object, the superclass of any class.
	 *********************
	 */
	public String toString() {
		String resultString = "This is the weight matrix of the graph.\r\n" + weightMatrix;
		return resultString;
	}// Of toString

	/**
	 *********************
	 * The Dijkstra algorithm: shortest path from the source to all nodes.
	 * 
	 * @param paraSource
	 *            The source node.
	 * @return The distances to all nodes.
	 *********************
	 */
	public int[] dijkstra(int paraSource) {
		// Step 1. Initialize.
		int[] tempDistanceArray = new int[numNodes];
		for (int i = 0; i < numNodes; i++) {
			tempDistanceArray[i] = weightMatrix.getValue(paraSource, i);
		} // Of for i

		int[] tempParentArray = new int[numNodes];
		Arrays.fill(tempParentArray, paraSource);
		// -1 for no parent.
		tempParentArray[paraSource] = -1;

		// Visited nodes will not be considered further.
		boolean[] tempVisitedArray = new boolean[numNodes];
		tempVisitedArray[paraSource] = true;

		// Step 2. Main loops.
		int tempMinDistance;
		int tempBestNode = -1;
		for (int i = 0; i < numNodes - 1; i++) {
			// Step 2.1 Find out the best next node.
			tempMinDistance = Integer.MAX_VALUE;
			for (int j = 0; j < numNodes; j++) {
				// This node is visited.
				if (tempVisitedArray[j]) {
					continue;
				} // Of if

				if (tempMinDistance > tempDistanceArray[j]) {
					tempMinDistance = tempDistanceArray[j];
					tempBestNode = j;
				} // Of if
			} // Of for j

			tempVisitedArray[tempBestNode] = true;

			// Step 2.2 Prepare for the next round.
			for (int j = 0; j < numNodes; j++) {
				// This node is visited.
				if (tempVisitedArray[j]) {
					continue;
				} // Of if

				// This node cannot be reached.
				if (weightMatrix.getValue(tempBestNode, j) >= MAX_DISTANCE) {
					continue;
				} // Of if

				if (tempDistanceArray[j] > tempDistanceArray[tempBestNode]
						+ weightMatrix.getValue(tempBestNode, j)) {
					// Change the distance.
					tempDistanceArray[j] = tempDistanceArray[tempBestNode]
							+ weightMatrix.getValue(tempBestNode, j);
					// Change the parent.
					tempParentArray[j] = tempBestNode;
				} // Of if
			} // Of for j

			// For test
			System.out.println("The distance to each node: " + Arrays.toString(tempDistanceArray));
			System.out.println("The parent of each node: " + Arrays.toString(tempParentArray));
		} // Of for i

		// Step 3. Output for debug.
		System.out.println("Finally");
		System.out.println("The distance to each node: " + Arrays.toString(tempDistanceArray));
		System.out.println("The parent of each node: " + Arrays.toString(tempParentArray));
		return tempDistanceArray;
	}// Of dijkstra

	/**
	 *********************
	 * The minimal spanning tree.
	 * 
	 * @return The total cost of the tree.
	 *********************
	 */
	public int prim() {
		// Step 1. Initialize.
		// Any node can be the source.
		int tempSource = 0;
		int[] tempDistanceArray = new int[numNodes];
		for (int i = 0; i < numNodes; i++) {
			tempDistanceArray[i] = weightMatrix.getValue(tempSource, i);
		} // Of for i

		int[] tempParentArray = new int[numNodes];
		Arrays.fill(tempParentArray, tempSource);
		// -1 for no parent.
		tempParentArray[tempSource] = -1;

		// Visited nodes will not be considered further.
		boolean[] tempVisitedArray = new boolean[numNodes];
		tempVisitedArray[tempSource] = true;

		// Step 2. Main loops.
		int tempMinDistance;
		int tempBestNode = -1;
		for (int i = 0; i < numNodes - 1; i++) {
			// Step 2.1 Find out the best next node.
			tempMinDistance = Integer.MAX_VALUE;
			for (int j = 0; j < numNodes; j++) {
				// This node is visited.
				if (tempVisitedArray[j]) {
					continue;
				} // Of if

				if (tempMinDistance > tempDistanceArray[j]) {
					tempMinDistance = tempDistanceArray[j];
					tempBestNode = j;
				} // Of if
			} // Of for j

			tempVisitedArray[tempBestNode] = true;

			// Step 2.2 Prepare for the next round.
			for (int j = 0; j < numNodes; j++) {
				// This node is visited.
				if (tempVisitedArray[j]) {
					continue;
				} // Of if

				// This node cannot be reached.
				if (weightMatrix.getValue(tempBestNode, j) >= MAX_DISTANCE) {
					continue;
				} // Of if

				// Attention: the difference from the Dijkstra algorithm.
				if (tempDistanceArray[j] > weightMatrix.getValue(tempBestNode, j)) {
					// Change the distance.
					tempDistanceArray[j] = weightMatrix.getValue(tempBestNode, j);
					// Change the parent.
					tempParentArray[j] = tempBestNode;
				} // Of if
			} // Of for j

			// For test
			System.out.println(
					"The selected distance for each node: " + Arrays.toString(tempDistanceArray));
			System.out.println("The parent of each node: " + Arrays.toString(tempParentArray));
		} // Of for i

		int resultCost = 0;
		for (int i = 0; i < numNodes; i++) {
			resultCost += tempDistanceArray[i];
		} // Of for i

		// Step 3. Output for debug.
		System.out.println("Finally");
		System.out.println("The parent of each node: " + Arrays.toString(tempParentArray));
		System.out.println("The total cost: " + resultCost);

		return resultCost;
	}// Of prim

	/**
	 *********************
	 * The entrance of the program.
	 * 
	 * @param args
	 *            Not used now.
	 *********************
	 */
	public static void main(String args[]) {
		Net tempNet0 = new Net(3);
		System.out.println(tempNet0);

		int[][] tempMatrix1 = { { 0, 9, 3, 6 }, { 5, 0, 2, 4 }, { 3, 2, 0, 1 }, { 2, 8, 7, 0 } };
		Net tempNet1 = new Net(tempMatrix1);
		System.out.println(tempNet1);

		// Dijkstra
		tempNet1.dijkstra(1);

		// An undirected net is required.
		int[][] tempMatrix2 = { { 0, 7, MAX_DISTANCE, 5, MAX_DISTANCE }, { 7, 0, 8, 9, 7 },
				{ MAX_DISTANCE, 8, 0, MAX_DISTANCE, 5 }, { 5, 9, MAX_DISTANCE, 0, 15, },
				{ MAX_DISTANCE, 7, 5, 15, 0 } };
		Net tempNet2 = new Net(tempMatrix2);
		tempNet2.prim();
	}// Of main
}// Of class Net

二、实现结果 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值