这里写自定义目录标题
基本原理
Dij算法和拓扑拍讯的基本原理很多这里不多说,dij算法核心思想就是理解T集合与P集合的含义,并且在程序执行时候记录每个节点的前级节点,可以求解一个点到其他所有点的最短路径。
##数据结构
##代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
public class CNode
{
public int ID;
public int Name;
public List<int> OutLink = new List<int>();//出节点的路段
public List<int> InLink = new List<int>();//进入节点的路段
public List<int> preNode = new List<int>();//前驱节点
public int Indegree;//入度
public int Torder;//拓扑序号
}
public class CLink
{
public int ID;
public int InNodeID;
public int OutNodeID;
public double Length;
}
public class CNetwork
{
public List<CNode> m_Node = new List<CNode>();
public List<CLink> m_Link = new List<CLink>();
public List<int> m_TopologicalOrder = new List<int>();//拓扑序
public List<int> P_list = new List<int>();//p标集合
public int[,] LinkNode;
public double[] LinkLength;
public double[] MinCost;
public int[] pre_list;//前节点集合
public void InitializationforDJ()
{
CLink pLink;
CNode pNode;
for (int node = 0; node < m_Node.Count; node++)
{
pNode = new CNode();
m_Node[node].OutLink.Clear();
}
LinkNode = new int[m_Link.Count, 2];
LinkLength = new double[m_Link.Count];
for (int link = 0; link < m_Link.Count; link++)
{
pLink = new CLink();
pLink = m_Link[link];
pNode = m_Node[pLink.InNodeID];
pNode.OutLink.Add(link);
LinkNode[link, 0] = pLink.InNodeID;
LinkNode[link, 1] = pLink.OutNodeID;
LinkLength[link] = pLink.Length;
}
MinCost = new double[m_Node.Count];
}
public void InitializationforLC()
{
CLink pLink;
CNode pNode1;
CNode pNode2;
for (int node = 0; node < m_Node.Count; node++)
{
m_Node[node].InLink.Clear();
m_Node[node].OutLink.Clear();
}
LinkNode = new int[m_Link.Count, 2];
LinkLength = new double[m_Link.Count];
for (int link = 0; link < m_Link.Count; link++)
{
pNode1 = new CNode();
pNode2 = new CNode();
pLink = new CLink();
pLink = m_Link[link];
pNode1 = m_Node[pLink.InNodeID];
pNode2 = m_Node[pLink.OutNodeID];
pNode1.OutLink.Add(link);
pNode2.InLink.Add(link);
LinkNode[link, 0] = pLink.InNodeID;
LinkNode[link, 1] = pLink.OutNodeID;
LinkLength[link] = pLink.Length;
}
MinCost = new double[m_Node.Count];
for (int i = 0; i < m_Node.Count; i++)
{
CNode pNode = new CNode();
pNode = m_Node[i];
pNode.Indegree = pNode.InLink.Count;
}
}
public void Dijkstra(int OriginID)
{
pre_list = new int[m_Node.Count];//前节点集合
bool[] bContained = new bool[m_Node.Count];
int node = 0, link = 0;
int renode = 0, index = 0;
for (node = 0; node < m_Node.Count; node++)
{
MinCost[node] = double.MaxValue;
pre_list[node] = -1;
bContained[node] = false;
}
P_list.Add(OriginID);
MinCost[OriginID] = 0;
int step= OriginID;
MinCost[OriginID] = 0;
bContained[OriginID] = true;
CNode pNode;
int pstep = 0;
StreamWriter sr = File.CreateText("DJoutput.txt");
StringBuilder sb = new StringBuilder();
while(P_list.Count<m_Node.Count)
{
pNode = new CNode();
pNode = m_Node[step];
for (node = 0; node < pNode.OutLink.Count; node++)
{
link = pNode.OutLink[node];
index = LinkNode[link, 1];//outnode
//T
if (MinCost[index] > MinCost[pNode.ID] + LinkLength[link])
{
MinCost[index] = MinCost[pNode.ID] + LinkLength[link];
pre_list[index] = pNode.ID;
}
}
//找到T标中最小的变为P标号
double minLength = double.MaxValue;
for (renode = 0; renode < m_Node.Count; renode++)
{
if ((MinCost[renode] < minLength) && (!bContained[renode]))
{
minLength = MinCost[renode];
pstep = step;
step = renode;
}
}
bContained[step] = true;
P_list.Add(renode);
}
public void TopologicalOrder(int OriginID)//拓扑排序
{
int node = 0, link = 0;
CNode pNode;
CLink pLink;
List<int> zeroIndegree = new List<int>();
int count = 0;
int index = 1;
m_TopologicalOrder.Clear();
while (count < m_Node.Count)//获得各个节点拓扑序号
{
for (node = 0; node < m_Node.Count; node++)
{
pNode = new CNode();
pNode = (CNode)m_Node[node];
if (pNode.Indegree == 0)
{
zeroIndegree.Add(pNode.ID);
}
else continue;
}
//int copyzeroIndegreeCount = zeroIndegree.Count;
while (zeroIndegree.Count > 0)
{
CNode pNode1 = new CNode();
pNode1 = (CNode)m_Node[zeroIndegree[0]];
pNode1.Torder = index;
zeroIndegree.Remove(zeroIndegree[0]);
m_TopologicalOrder.Add(pNode1.ID);
UpdateIndegree(pNode1);
index++;
count++;
}
}
//根据起点更新拓扑排序集合
if (m_TopologicalOrder[0] != OriginID)
{
for (node = 0; node < m_Node.Count; node++)
{
if (m_TopologicalOrder[node] == OriginID)
{
//int copy = m_TopologicalOrder[node];
m_TopologicalOrder[node] = m_TopologicalOrder[0];
m_TopologicalOrder[0] = OriginID;
}
}
}
}
public void UpdateIndegree(CNode pNode)//更新入度
{
pNode.Indegree = 1000;
int node = 0;
for (node = 0; node < pNode.OutLink.Count; node++)
{
CLink pLink = new CLink();
pLink = m_Link[pNode.OutLink[node]];
m_Node[pLink.OutNodeID].Indegree--;
}
}
public void LabelCorrecting(int OriginID)
{
int node = 0, link = 0;
pre_list = new int[m_Node.Count];
for (node = 0; node < m_Node.Count; node++)
{
MinCost[node] = double.MaxValue;
pre_list[node] = -1;
}
CNode pNode;
MinCost[OriginID] = 0;
for (int i = 0; i < m_TopologicalOrder.Count; i++)
{
pNode=new CNode();
pNode = m_Node[m_TopologicalOrder[i]];
for (node = 0; node < pNode.OutLink.Count; node++)
{
link = pNode.OutLink[node];
int index = LinkNode[link, 1];//outnode
//T
if (MinCost[index] > MinCost[pNode.ID] + LinkLength[link])
{
MinCost[index] = MinCost[pNode.ID] + LinkLength[link];
m_Node[index].OutLink.Add(pNode.ID);
pre_list[pNode.ID] = index;
}
}
}
}
}
2. 窗体程序
(2) Form.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace DJandLB
{
public partial class Form1 : Form
{
CNetwork pNetwork;
public Form1()
{
InitializeComponent();
}
void LoaddataforDJ()
{
pNetwork = new CNetwork();
String datapath;
datapath = Directory.GetCurrentDirectory();
datapath += "\\DJNode.dat";
pNetwork.ReadNode(datapath);
datapath = Directory.GetCurrentDirectory();
datapath += "\\DJLink.dat";
pNetwork.ReadLink(datapath);
}
void LoaddataforLC()
{
pNetwork = new CNetwork();
String datapath;
datapath = Directory.GetCurrentDirectory();
datapath += "\\LCNode.dat";
pNetwork.ReadNode(datapath);
datapath = Directory.GetCurrentDirectory();
datapath += "\\LCLink.dat";
pNetwork.ReadLink(datapath);
}
private void btn_Dijkstra_Click(object sender, EventArgs e)
{
LoaddataforDJ();
pNetwork.InitializationforDJ();
pNetwork.Dijkstra(0);
//pNetwork.SaveShortestPathforDJ("DJoutput.txt");
MessageBox.Show("ok!");
}
private void btn_LC_Click(object sender, EventArgs e)
{
int OriginID = 2;
LoaddataforLC();
pNetwork.InitializationforLC();
pNetwork.TopologicalOrder(OriginID);
pNetwork.LabelCorrecting(OriginID);
pNetwork.SaveShortestPathforLC(OriginID,"LCoutput.txt");
MessageBox.Show("ok!");
}
}
}