实验任务二
迪杰斯特拉算法实验
1、 系统设计要求
建立图的表示模块,在建立图之后从单源点开始求各最短路径,并显示出来。
1、 根据图1所示节点的洪泛信息,以邻接矩阵为存储结构建立图2所示无向图
2、利用Dijkstra算法,编程实现任意指定节点的路由转发表并输出该转发表(即任意指定一个节点,能计算出该节点到其它节点的最短路径,并构造出路由转发表,转发表如表1所示)。
2、 设计思路与方案
1) 设计思路
1、 建立相关洪泛信息文件,通过代码实现文件的读取。
2、 通过代码将洪泛信息文件读取并用领接矩阵进行存储。然后在屏幕上输出该洪泛信息的领接矩阵表。
3、 从命令行读取用户输入的结点信息。
4、 计算出该用户输入得结点信息与其他结点的最短路径以及下一跳结点。
2) 程序总体框图
3) 程序算法模块
模块一
//1.读取文件并且判断出总共有多少个结点数目:(结点数存储在NumberOfNodes)
private void setNumberOfNodes(){
NumberOfNodes=0;
int[] user1={0,0,0};
int[] user2={0,0,0};
int i=0;
int j=0;
try {
String encoding = "GBK" ;
File file = new File("dataOfNodes.txt");
if (file.isFile() && file.exists()) {
InputStreamReader read = new InputStreamReader(
new FileInputStream(file), encoding);
bufferedReader = new BufferedReader(read);
String lineTXT = null ;
while ((lineTXT = bufferedReader.readLine()) != null ) {
i=0;
String[] result=lineTXT.toString().trim().split("/");
if(j%2==0)
{
for(String token:result){
user1[i]=Integer.parseInt(token);
//System.out.println(token);
i=i+1;
}
}else
{
for(String token:result){
user2[i]=Integer.parseInt(token);
//System.out.println(token);
i=i+1;
}
}
if((user1[0]!=user2[0])&&j!=0)
{
NumberOfNodes++;
}
j++;
}
}else {
System.out.println( "can`t find the file" );
}
} catch (Exception e) {
System.out.println( "read with wrong" );
e.printStackTrace();
} finally{
}
}
模块二
//2.由上面的方法已知结点数,则就已知领接矩阵的行数列数,只需将文件的信息存储在领接矩阵中。(若两节点不相连则距离为10000)
public void setData(){
setNumberOfNodes();
int node=NumberOfNodes+1;
Data=new int[node][node];
for(int i=0;i<node;i++){
for(int j=0;j<node;j++){
Data[i][j]=10000;
}
}
try{
String encoding = "GBK" ;
File file = new File("dataOfNodes.txt");
if (file.isFile() && file.exists()) {
InputStreamReader read = new InputStreamReader(
new FileInputStream(file), encoding);
bufferedReader2 = new BufferedReader(read);
String lineTXT = null ;
while ((lineTXT = bufferedReader2.readLine()) != null ) {
int k=0;
int[] user={0,0,0};
String[] result=lineTXT.toString().trim().split("/");
for(String token:result){
user[k]=Integer.parseInt(token);
k=k+1;
}
Data[user[0]-1][user[1]-1]=user[2];
}
}else {
System.out.println( "can`t find the file" );
}
}catch (Exception e) {
System.out.println( "read with wrong" );
e.printStackTrace();
} finally{ }
}
模块三
//3.迪杰斯特拉算法计算最短路径:
public static int[] Dijsktra(int[][]weight,int start){
int length = weight.length;
int[] shortPath = new int[length];//存放从start到各个点的最短距离
shortPath[start] = 0;//start到他本身的距离最短为0
String path[] = new String[length];//存放从start点到各点的最短路径的字符串表示
for(int i=0;i<length;i++){
path[i] = (start+1)+"->"+(i+1);
}
int visited[] = new int[length];//标记当前该顶点的最短路径是否已经求出,1表示已经求出
visited[start] = 1;//start点的最短距离已经求出
for(int count = 1;count<length;count++){
int k=-1;
int dmin = Integer.MAX_VALUE;
for(int i=0;i<length;i++){
if(visited[i]==0 && weight[start][i]<dmin){
dmin = weight[start][i];
k=i;
}
}
//选出一个距离start最近的未标记的顶点 将新选出的顶点标记为以求出最短路径,且到start的最短路径为dmin。
shortPath[k] = dmin;
visited[k] = 1;
//以k为中间点,修正从start到未访问各点的距离
for(int i=0;i<length;i++){
if(visited[i]==0 && weight[start][k]+weight[k][i]<weight[start][i]){
weight[start][i] = weight[start][k]+weight[k][i];
path[i] = path[k]+"->"+(i+1);
}
}
}
for(int i=0;i<length;i++){
System.out.println("从"+(start+1)+"出发到"+(i+1)+"的最短路径为:"+path[i]+"="+shortPath[i]);
}
return shortPath;
}
3.运行结果及完整代码
起点为2
起点为3
完整代码
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.*;
class test{
public static void main(String[] args){
Graph graph=new Graph();
graph.setData();
graph.show();
String input = "";
InputStreamReader in = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(in);
System.out.print("请确定起点:");
try {
input = bufferedReader.readLine();
String result=input.toString().trim();
int want=Integer.parseInt(result);
int[] dijsktra=Graph.Dijsktra(graph.Data, want-1);
System.out.println("起点"+(want)+"到各结点最短路径:");
for(int path:dijsktra){
System.out.printf("%5d",path);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Graph{
int NumberOfNodes;
int[][] Data;
private BufferedReader bufferedReader;
private BufferedReader bufferedReader2;
public static int[] Dijsktra(int[][]weight,int start){
int length = weight.length;
int[] shortPath = new int[length];//存放从start到各个点的最短距离
shortPath[start] = 0;//start到他本身的距离最短为0
String path[] = new String[length];//存放从start点到各点的最短路径的字符串表示
for(int i=0;i<length;i++){
path[i] = (start+1)+"->"+(i+1);
}
int visited[] = new int[length];//标记当前该顶点的最短路径是否已经求出,1表示已经求出
visited[start] = 1;//start点的最短距离已经求出
for(int count = 1;count<length;count++){
int k=-1;
int dmin = Integer.MAX_VALUE;
for(int i=0;i<length;i++){
if(visited[i]==0 && weight[start][i]<dmin){
dmin = weight[start][i];
k=i;
}
}
//选出一个距离start最近的未标记的顶点 将新选出的顶点标记为以求出最短路径,且到start的最短路径为dmin。
shortPath[k] = dmin;
visited[k] = 1;
//以k为中间点,修正从start到未访问各点的距离
for(int i=0;i<length;i++){
if(visited[i]==0 && weight[start][k]+weight[k][i]<weight[start][i]){
weight[start][i] = weight[start][k]+weight[k][i];
path[i] = path[k]+"->"+(i+1);
}
}
}
for(int i=0;i<length;i++){
System.out.println("从"+(start+1)+"出发到"+(i+1)+"的最短路径为:"+path[i]+"="+shortPath[i]);
}
return shortPath;
}
private void setNumberOfNodes(){
NumberOfNodes=0;
int[] user1={0,0,0};
int[] user2={0,0,0};
int i=0;
int j=0;
try {
String encoding = "GBK" ;
File file = new File("dataOfNodes.txt");
if (file.isFile() && file.exists()) {
InputStreamReader read = new InputStreamReader(
new FileInputStream(file), encoding);
bufferedReader = new BufferedReader(read);
String lineTXT = null ;
while ((lineTXT = bufferedReader.readLine()) != null ) {
i=0;
String[] result=lineTXT.toString().trim().split("/");
if(j%2==0)
{
for(String token:result){
user1[i]=Integer.parseInt(token);
//System.out.println(token);
i=i+1;
}
}else
{
for(String token:result){
user2[i]=Integer.parseInt(token);
//System.out.println(token);
i=i+1;
}
}
if((user1[0]!=user2[0])&&j!=0)
{
NumberOfNodes++;
}
j++;
}
}else {
System.out.println( "can`t find the file" );
}
} catch (Exception e) {
System.out.println( "read with wrong" );
e.printStackTrace();
} finally{
}
}
public void setData(){
setNumberOfNodes();
int node=NumberOfNodes+1;
Data=new int[node][node];
for(int i=0;i<node;i++){
for(int j=0;j<node;j++){
Data[i][j]=10000;
}
}
try{
String encoding = "GBK" ;
File file = new File("dataOfNodes.txt");
if (file.isFile() && file.exists()) {
InputStreamReader read = new InputStreamReader(
new FileInputStream(file), encoding);
bufferedReader2 = new BufferedReader(read);
String lineTXT = null ;
while ((lineTXT = bufferedReader2.readLine()) != null ) {
int k=0;
int[] user={0,0,0};
String[] result=lineTXT.toString().trim().split("/");
for(String token:result){
user[k]=Integer.parseInt(token);
k=k+1;
}
Data[user[0]-1][user[1]-1]=user[2];
}
}else {
System.out.println( "can`t find the file" );
}
}catch (Exception e) {
System.out.println( "read with wrong" );
e.printStackTrace();
} finally{ }
}
public void show(){
int node=NumberOfNodes+1;
for(int i=0;i<node;i++){
for(int j=0;j<node;j++){
System.out.printf("%6d",Data[i][j]);
}
System.out.printf("\n");
}
}
}