[C#]最短路徑(視窗版)
執行結果:
// =========================================================
// 從某一點到其餘各點的最短路徑
// Dijkstra() Dijkstra演算法
// find_Shortest() 找出Decided[]=0且Dist最小者
// Dist(N) 從起點到各點的最短距離
// PreNode(N) 各點最短路徑中的前一個頂點
// Decided(N) 最短路徑是否已決定
// 作者: Chris C.S Huang
// 程試語言: VC# 2008 Expression Edition
//=========================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public const int N = 8; //N是總頂點數
const int NC = 100000;
//路網圖, NC表示沒有直接連接
public static int[,] Cost = new int[,] {{ 0, 3, 5, 4, NC, NC, NC, NC},
{ 3, 0, NC, 4, NC, NC, NC, NC},
{ 5, NC, 0, 3, NC, 2, NC, NC},
{ 4, 4, 3, 0, 7, 3, NC, NC},
{NC, NC, NC, 7, 0, NC, 6, 1},
{NC, NC, 2, 3, NC, 0, 4, 2},
{NC, NC, NC, NC, 6, 4, 0, 3},
{NC, NC, NC, NC, 1, 2, 3, 0}};
public static int[] Dist = new int[N];
public static int[] Decided = new int[N];
public static int[] PreNode = new int[N];
public static int Start, Destination;
string routeStr;
public Form1()
{
InitializeComponent();
Start = 0; Destination = 0;
comboBox1.Text = "0"; comboBox2.Text = "0";
pictureBox1.Image = Image.FromFile("Route.jpg");
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Start = Convert.ToInt16(comboBox1.Text);
Dijstra(Start);
textBoxDistance.Text = Dist[Destination].ToString();//Dist陣列是行進距離
routeStr = PrintPath(Start, Destination);
textBoxRoute.Text = routeStr;
}
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
Destination = Convert.ToInt16(comboBox2.Text);
Dijstra(Start);
textBoxDistance.Text = Dist[Destination].ToString();
routeStr = PrintPath(Start, Destination);
// Console.WriteLine("N{0} --> N{1} Distance == {2}", Start, Destination, Dist[Destination]); //Dist陣列是行進距離
textBoxRoute.Text = routeStr;
}
unsafe public static void Dijstra(int Start) ///Start是指定的起點, 例如0表示N0 ; 編譯時必須使用Unsafe選項
{
int Nd, i, w;
for (i = 0; i < N; i++)
{
Dist[i] = Cost[Start, i]; //初設為Cost[]陣列的第Start列
PreNode[i] = Start; //由Start開始走到任意一點
Decided[i] = 0;
}
Decided[Start] = 1;
for (i = 0; i < N; i++)
{
find_Shortest(&Nd); ///找尚未找過且與V0最近的節點Nd
if (PreNode[Nd] == -1)
PreNode[Nd] = Start;
Decided[Nd] = 1;
for (w = 0; w < N; w++)
{
if (Decided[w] == 0 && Dist[w] > (Dist[Nd] + Cost[Nd, w]))
{
Dist[w] = Dist[Nd] + Cost[Nd, w];
PreNode[w] = Nd;
}
}
}
}
unsafe static void find_Shortest(int* Nd) //找出連接目前節點的所有點中距離最短的節點Nd
{
int low = 0, lowest = 32767, i = 0;
for (i = 0; i < N; i++)
{
if (Decided[i] == 0 && Dist[i] < lowest)
{
lowest = Dist[i];
low = i;
}
}
*Nd = low;
}
public static string PrintPath(int Start, int Nd) // Start: 起始點, Nd終點
{
int i;
Stack<int> stack = new Stack<int>();
string node;
stack.Push(Nd);
i = PreNode[Nd];
while (i != Start)
{
stack.Push(i);
i = PreNode[i];
}
stack.Push(i);
string routeStr = "";
while (stack.Count > 0)
{
node = stack.Pop().ToString();
routeStr = routeStr + " " + node;
}
return routeStr;
}
}
}