路径规划(最短路径)算法C#实现
来自http://zhuweisky.cnblogs.com/archive/2005/09/29/246677.html
以前空闲的时候用C#实现的路径规划算法,今日贴它出来,看大家有没有更好的实现方案。关于路径规划(最短路径)算法的背景知识,大家可以参考《C++算法--图算法》一书。
该图算法描述的是这样的场景:图由节点和带有方向的边构成,每条边都有相应的权值,路径规划(最短路径)算法就是要找出从节点A到节点B的累积权值最小的路径。
首先,我们可以将“有向边”抽象为Edge类:
public class Node
{
private string iD ;
private ArrayList edgeList ;//Edge的集合--出边表

public Node(string id )
{
this.iD = id ;
this.edgeList = new ArrayList() ;
}

property
}
在计算的过程中,我们需要记录到达每一个节点权值最小的路径,这个抽象可以用PassedPath类来表示:
另外,还需要一个表PlanCourse来记录规划的中间结果,即它管理了每一个节点的PassedPath。
/// <summary>
/// PlanCourse 缓存从源节点到其它任一节点的最小权值路径=》路径表
/// </summary>
public class PlanCourse
{
private Hashtable htPassedPath ;
#region ctor
public PlanCourse(ArrayList nodeList ,string originID)
{
this.htPassedPath = new Hashtable() ;
Node originNode = null ;
foreach(Node node in nodeList)
{
if(node.ID == originID)
{
originNode = node ;
}
else
{
PassedPath pPath = new PassedPath(node.ID) ;
this.htPassedPath.Add(node.ID ,pPath) ;
}
}
if(originNode == null)
{
throw new Exception("The origin node is not exist !") ;
}
this.InitializeWeight(originNode) ;
}
private void InitializeWeight(Node originNode)
{
if((originNode.EdgeList == null) ||(originNode.EdgeList.Count == 0))
{
return ;
}
foreach(Edge edge in originNode.EdgeList)
{
PassedPath pPath = this[edge.EndNodeID] ;
if(pPath == null)
{
continue ;
}
pPath.PassedIDList.Add(originNode.ID) ;
pPath.Weight = edge.Weight ;
}
}
#endregion
public PassedPath this[string nodeID]
{
get
{
return (PassedPath)this.htPassedPath[nodeID] ;
}
}
}
在所有的基础构建好后,路径规划算法就很容易实施了,该算法主要步骤如下:
(1)用一张表(PlanCourse)记录源点到任何其它一节点的最小权值,初始化这张表时,如果源点能直通某节点,则权值设为对应的边的权,否则设为double.MaxValue。
(2)选取没有被处理并且当前累积权值最小的节点TargetNode,用其边的可达性来更新到达其它节点的路径和权值(如果其它节点 经此节点后权值变小则更新,否则不更新),然后标记TargetNode为已处理。
(3)重复(2),直至所有的可达节点都被处理一遍。
(4)从PlanCourse表中获取目的点的PassedPath,即为结果。
下面就来看上述步骤的实现,该实现被封装在RoutePlanner类中:
2006.05.22 应众多朋友要求,下面给出一个简单示例:
RoutePlanner.Plan 过程详解:
(1)用一张表(PlanCourse)记录源点到任何其它一节点的最小权值,初始化这张表时,如果源点能直通某节点,则权值设为对应的
边的权,否则设为double.MaxValue
(2)选取没有被处理并且当前累积权值最小的节点TargetNode,用其边的可达性来更新到达其它节点的路径和权值(如果其它节点
经此节点后权值变小则更新,否则不更新),然后标记TargetNode为已处理
(3)重复(2),直至所有的可达节点都被处理一遍。
(4)从PlanCourse表中获取目的点的PassedPath,即为结果。
以前空闲的时候用C#实现的路径规划算法,今日贴它出来,看大家有没有更好的实现方案。关于路径规划(最短路径)算法的背景知识,大家可以参考《C++算法--图算法》一书。
该图算法描述的是这样的场景:图由节点和带有方向的边构成,每条边都有相应的权值,路径规划(最短路径)算法就是要找出从节点A到节点B的累积权值最小的路径。
首先,我们可以将“有向边”抽象为Edge类:
public class Edge
{
public string StartNodeID ;
public string EndNodeID ;
public double Weight ; //权值,代价
}
节点则抽象成Node类,一个节点上挂着以此节点作为起点的“出边”表。{
public string StartNodeID ;
public string EndNodeID ;
public double Weight ; //权值,代价
}













在计算的过程中,我们需要记录到达每一个节点权值最小的路径,这个抽象可以用PassedPath类来表示:
/// <summary>
/// PassedPath 用于缓存计算过程中的到达某个节点的权值最小的路径
/// </summary>
public class PassedPath
{
private string curNodeID ;
private bool beProcessed ; //是否已被处理
private double weight ; //累积的权值
private ArrayList passedIDList ; //路径
public PassedPath(string ID)
{
this.curNodeID = ID ;
this.weight = double.MaxValue ;
this.passedIDList = new ArrayList() ;
this.beProcessed = false ;
}
#region property
public bool BeProcessed
{
get
{
return this.beProcessed ;
}
set
{
this.beProcessed = value ;
}
}
public string CurNodeID
{
get
{
return this.curNodeID ;
}
}
public double Weight
{
get
{
return this.weight ;
}
set
{
this.weight = value ;
}
}
public ArrayList PassedIDList
{
get
{
return this.passedIDList ;
}
}
#endregion
}
/// PassedPath 用于缓存计算过程中的到达某个节点的权值最小的路径
/// </summary>
public class PassedPath
{
private string curNodeID ;
private bool beProcessed ; //是否已被处理
private double weight ; //累积的权值
private ArrayList passedIDList ; //路径
public PassedPath(string ID)
{
this.curNodeID = ID ;
this.weight = double.MaxValue ;
this.passedIDList = new ArrayList() ;
this.beProcessed = false ;
}
#region property
public bool BeProcessed
{
get
{
return this.beProcessed ;
}
set
{
this.beProcessed = value ;
}
}
public string CurNodeID
{
get
{
return this.curNodeID ;
}
}
public double Weight
{
get
{
return this.weight ;
}
set
{
this.weight = value ;
}
}
public ArrayList PassedIDList
{
get
{
return this.passedIDList ;
}
}
#endregion
}
另外,还需要一个表PlanCourse来记录规划的中间结果,即它管理了每一个节点的PassedPath。
/// <summary>
/// PlanCourse 缓存从源节点到其它任一节点的最小权值路径=》路径表
/// </summary>
public class PlanCourse
{
private Hashtable htPassedPath ;
#region ctor
public PlanCourse(ArrayList nodeList ,string originID)
{
this.htPassedPath = new Hashtable() ;
Node originNode = null ;
foreach(Node node in nodeList)
{
if(node.ID == originID)
{
originNode = node ;
}
else
{
PassedPath pPath = new PassedPath(node.ID) ;
this.htPassedPath.Add(node.ID ,pPath) ;
}
}
if(originNode == null)
{
throw new Exception("The origin node is not exist !") ;
}
this.InitializeWeight(originNode) ;
}
private void InitializeWeight(Node originNode)
{
if((originNode.EdgeList == null) ||(originNode.EdgeList.Count == 0))
{
return ;
}
foreach(Edge edge in originNode.EdgeList)
{
PassedPath pPath = this[edge.EndNodeID] ;
if(pPath == null)
{
continue ;
}
pPath.PassedIDList.Add(originNode.ID) ;
pPath.Weight = edge.Weight ;
}
}
#endregion
public PassedPath this[string nodeID]
{
get
{
return (PassedPath)this.htPassedPath[nodeID] ;
}
}
}
在所有的基础构建好后,路径规划算法就很容易实施了,该算法主要步骤如下:
(1)用一张表(PlanCourse)记录源点到任何其它一节点的最小权值,初始化这张表时,如果源点能直通某节点,则权值设为对应的边的权,否则设为double.MaxValue。
(2)选取没有被处理并且当前累积权值最小的节点TargetNode,用其边的可达性来更新到达其它节点的路径和权值(如果其它节点 经此节点后权值变小则更新,否则不更新),然后标记TargetNode为已处理。
(3)重复(2),直至所有的可达节点都被处理一遍。
(4)从PlanCourse表中获取目的点的PassedPath,即为结果。
下面就来看上述步骤的实现,该实现被封装在RoutePlanner类中:
/// <summary>
/// RoutePlanner 提供图算法中常用的路径规划功能。
/// 2005.09.06
/// </summary>
public class RoutePlanner
{
public RoutePlanner()
{
}
#region Paln
//获取权值最小的路径
public RoutePlanResult Paln(ArrayList nodeList ,string originID ,string destID)
{
PlanCourse planCourse = new PlanCourse(nodeList ,originID) ;
Node curNode = this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;
#region 计算过程
while(curNode != null)
{
PassedPath curPath = planCourse[curNode.ID] ;
foreach(Edge edge in curNode.EdgeList)
{
PassedPath targetPath = planCourse[edge.EndNodeID] ;
double tempWeight = curPath.Weight + edge.Weight ;
if(tempWeight < targetPath.Weight)
{
targetPath.Weight = tempWeight ;
targetPath.PassedIDList.Clear() ;
for(int i=0 ;i<curPath.PassedIDList.Count ;i++)
{
targetPath.PassedIDList.Add(curPath.PassedIDList[i].ToString()) ;
}
targetPath.PassedIDList.Add(curNode.ID) ;
}
}
//标志为已处理
planCourse[curNode.ID].BeProcessed = true ;
//获取下一个未处理节点
curNode = this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;
}
#endregion
//表示规划结束
return this.GetResult(planCourse ,destID) ;
}
#endregion
#region private method
#region GetResult
//从PlanCourse表中取出目标节点的PassedPath,这个PassedPath即是规划结果
private RoutePlanResult GetResult(PlanCourse planCourse ,string destID)
{
PassedPath pPath = planCourse[destID] ;
if(pPath.Weight == int.MaxValue)
{
RoutePlanResult result1 = new RoutePlanResult(null ,int.MaxValue) ;
return result1 ;
}
string[] passedNodeIDs = new string[pPath.PassedIDList.Count] ;
for(int i=0 ;i<passedNodeIDs.Length ;i++)
{
passedNodeIDs[i] = pPath.PassedIDList[i].ToString() ;
}
RoutePlanResult result = new RoutePlanResult(passedNodeIDs ,pPath.Weight) ;
return result ;
}
#endregion
#region GetMinWeightRudeNode
//从PlanCourse取出一个当前累积权值最小,并且没有被处理过的节点
private Node GetMinWeightRudeNode(PlanCourse planCourse ,ArrayList nodeList ,string originID)
{
double weight = double.MaxValue ;
Node destNode = null ;
foreach(Node node in nodeList)
{
if(node.ID == originID)
{
continue ;
}
PassedPath pPath = planCourse[node.ID] ;
if(pPath.BeProcessed)
{
continue ;
}
if(pPath.Weight < weight)
{
weight = pPath.Weight ;
destNode = node ;
}
}
return destNode ;
}
#endregion
#endregion
}
/// RoutePlanner 提供图算法中常用的路径规划功能。
/// 2005.09.06
/// </summary>
public class RoutePlanner
{
public RoutePlanner()
{
}
#region Paln
//获取权值最小的路径
public RoutePlanResult Paln(ArrayList nodeList ,string originID ,string destID)
{
PlanCourse planCourse = new PlanCourse(nodeList ,originID) ;
Node curNode = this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;
#region 计算过程
while(curNode != null)
{
PassedPath curPath = planCourse[curNode.ID] ;
foreach(Edge edge in curNode.EdgeList)
{
PassedPath targetPath = planCourse[edge.EndNodeID] ;
double tempWeight = curPath.Weight + edge.Weight ;
if(tempWeight < targetPath.Weight)
{
targetPath.Weight = tempWeight ;
targetPath.PassedIDList.Clear() ;
for(int i=0 ;i<curPath.PassedIDList.Count ;i++)
{
targetPath.PassedIDList.Add(curPath.PassedIDList[i].ToString()) ;
}
targetPath.PassedIDList.Add(curNode.ID) ;
}
}
//标志为已处理
planCourse[curNode.ID].BeProcessed = true ;
//获取下一个未处理节点
curNode = this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;
}
#endregion
//表示规划结束
return this.GetResult(planCourse ,destID) ;
}
#endregion
#region private method
#region GetResult
//从PlanCourse表中取出目标节点的PassedPath,这个PassedPath即是规划结果
private RoutePlanResult GetResult(PlanCourse planCourse ,string destID)
{
PassedPath pPath = planCourse[destID] ;
if(pPath.Weight == int.MaxValue)
{
RoutePlanResult result1 = new RoutePlanResult(null ,int.MaxValue) ;
return result1 ;
}
string[] passedNodeIDs = new string[pPath.PassedIDList.Count] ;
for(int i=0 ;i<passedNodeIDs.Length ;i++)
{
passedNodeIDs[i] = pPath.PassedIDList[i].ToString() ;
}
RoutePlanResult result = new RoutePlanResult(passedNodeIDs ,pPath.Weight) ;
return result ;
}
#endregion
#region GetMinWeightRudeNode
//从PlanCourse取出一个当前累积权值最小,并且没有被处理过的节点
private Node GetMinWeightRudeNode(PlanCourse planCourse ,ArrayList nodeList ,string originID)
{
double weight = double.MaxValue ;
Node destNode = null ;
foreach(Node node in nodeList)
{
if(node.ID == originID)
{
continue ;
}
PassedPath pPath = planCourse[node.ID] ;
if(pPath.BeProcessed)
{
continue ;
}
if(pPath.Weight < weight)
{
weight = pPath.Weight ;
destNode = node ;
}
}
return destNode ;
}
#endregion
#endregion
}
2006.05.22 应众多朋友要求,下面给出一个简单示例:
RoutePlanner.Plan 过程详解:
(1)用一张表(PlanCourse)记录源点到任何其它一节点的最小权值,初始化这张表时,如果源点能直通某节点,则权值设为对应的
边的权,否则设为double.MaxValue
(2)选取没有被处理并且当前累积权值最小的节点TargetNode,用其边的可达性来更新到达其它节点的路径和权值(如果其它节点
经此节点后权值变小则更新,否则不更新),然后标记TargetNode为已处理
(3)重复(2),直至所有的可达节点都被处理一遍。
(4)从PlanCourse表中获取目的点的PassedPath,即为结果。
[STAThread]
static void Main(string[] args)
{
ArrayList nodeList = new ArrayList() ;
//***************** B Node *******************
Node aNode = new Node("A") ;
nodeList.Add(aNode) ;
//A -> B
Edge aEdge1 = new Edge() ;
aEdge1.StartNodeID = aNode.ID ;
aEdge1.EndNodeID = "B" ;
aEdge1.Weight = 10 ;
aNode.EdgeList.Add(aEdge1) ;
//A -> C
Edge aEdge2 = new Edge() ;
aEdge2.StartNodeID = aNode.ID ;
aEdge2.EndNodeID = "C" ;
aEdge2.Weight = 20 ;
aNode.EdgeList.Add(aEdge2) ;
//A -> E
Edge aEdge3 = new Edge() ;
aEdge3.StartNodeID = aNode.ID ;
aEdge3.EndNodeID = "E" ;
aEdge3.Weight = 30 ;
aNode.EdgeList.Add(aEdge3) ;
//***************** B Node *******************
Node bNode = new Node("B") ;
nodeList.Add(bNode) ;
//B -> C
Edge bEdge1 = new Edge() ;
bEdge1.StartNodeID = bNode.ID ;
bEdge1.EndNodeID = "C" ;
bEdge1.Weight = 5 ;
bNode.EdgeList.Add(bEdge1) ;
//B -> E
Edge bEdge2 = new Edge() ;
bEdge2.StartNodeID = bNode.ID ;
bEdge2.EndNodeID = "E" ;
bEdge2.Weight = 10 ;
bNode.EdgeList.Add(bEdge2) ;
//***************** C Node *******************
Node cNode = new Node("C") ;
nodeList.Add(cNode) ;
//C -> D
Edge cEdge1 = new Edge() ;
cEdge1.StartNodeID = cNode.ID ;
cEdge1.EndNodeID = "D" ;
cEdge1.Weight = 30 ;
cNode.EdgeList.Add(cEdge1) ;
//***************** D Node *******************
Node dNode = new Node("D") ;
nodeList.Add(dNode) ;
//***************** C Node *******************
Node eNode = new Node("E") ;
nodeList.Add(eNode) ;
//C -> D
Edge eEdge1 = new Edge() ;
eEdge1.StartNodeID = eNode.ID ;
eEdge1.EndNodeID = "D" ;
eEdge1.Weight = 20 ;
eNode.EdgeList.Add(eEdge1) ;
RoutePlanner planner = new RoutePlanner() ;
RoutePlanResult result = planner.Paln(nodeList ,"A" ,"D") ;
planner = null ;
}
static void Main(string[] args)
{
ArrayList nodeList = new ArrayList() ;
//***************** B Node *******************
Node aNode = new Node("A") ;
nodeList.Add(aNode) ;
//A -> B
Edge aEdge1 = new Edge() ;
aEdge1.StartNodeID = aNode.ID ;
aEdge1.EndNodeID = "B" ;
aEdge1.Weight = 10 ;
aNode.EdgeList.Add(aEdge1) ;
//A -> C
Edge aEdge2 = new Edge() ;
aEdge2.StartNodeID = aNode.ID ;
aEdge2.EndNodeID = "C" ;
aEdge2.Weight = 20 ;
aNode.EdgeList.Add(aEdge2) ;
//A -> E
Edge aEdge3 = new Edge() ;
aEdge3.StartNodeID = aNode.ID ;
aEdge3.EndNodeID = "E" ;
aEdge3.Weight = 30 ;
aNode.EdgeList.Add(aEdge3) ;
//***************** B Node *******************
Node bNode = new Node("B") ;
nodeList.Add(bNode) ;
//B -> C
Edge bEdge1 = new Edge() ;
bEdge1.StartNodeID = bNode.ID ;
bEdge1.EndNodeID = "C" ;
bEdge1.Weight = 5 ;
bNode.EdgeList.Add(bEdge1) ;
//B -> E
Edge bEdge2 = new Edge() ;
bEdge2.StartNodeID = bNode.ID ;
bEdge2.EndNodeID = "E" ;
bEdge2.Weight = 10 ;
bNode.EdgeList.Add(bEdge2) ;
//***************** C Node *******************
Node cNode = new Node("C") ;
nodeList.Add(cNode) ;
//C -> D
Edge cEdge1 = new Edge() ;
cEdge1.StartNodeID = cNode.ID ;
cEdge1.EndNodeID = "D" ;
cEdge1.Weight = 30 ;
cNode.EdgeList.Add(cEdge1) ;
//***************** D Node *******************
Node dNode = new Node("D") ;
nodeList.Add(dNode) ;
//***************** C Node *******************
Node eNode = new Node("E") ;
nodeList.Add(eNode) ;
//C -> D
Edge eEdge1 = new Edge() ;
eEdge1.StartNodeID = eNode.ID ;
eEdge1.EndNodeID = "D" ;
eEdge1.Weight = 20 ;
eNode.EdgeList.Add(eEdge1) ;
RoutePlanner planner = new RoutePlanner() ;
RoutePlanResult result = planner.Paln(nodeList ,"A" ,"D") ;
planner = null ;
}
0
0
(请您对文章做出评价)
发表评论
盒模型bug的解决方法
作者:阿捷 2004-7-22 22:37:07
作者:阿捷 2004-7-22 22:37:07
//==========================================================================
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
/**
* @author 周振興
* @version 1.00
*/
public class Edge {
public String StartNodeID;
public String EndNodeID;
public double Weight;
/**
* @return Returns the endNodeID.
*/
public String getEndNodeID() {
return EndNodeID;
}
/**
* @param endNodeID The endNodeID to set.
*/
public void setEndNodeID(String endNodeID) {
EndNodeID = endNodeID;
}
/**
* @return Returns the startNodeID.
*/
public String getStartNodeID() {
return StartNodeID;
}
/**
* @param startNodeID The startNodeID to set.
*/
public void setStartNodeID(String startNodeID) {
StartNodeID = startNodeID;
}
/**
* @return Returns the weight.
*/
public double getWeight() {
return Weight;
}
/**
* @param weight The weight to set.
*/
public void setWeight(double weight) {
Weight = weight;
}
}
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
/**
* @author 周振興
* @version 1.00
*/
public class Edge {
public String StartNodeID;
public String EndNodeID;
public double Weight;
/**
* @return Returns the endNodeID.
*/
public String getEndNodeID() {
return EndNodeID;
}
/**
* @param endNodeID The endNodeID to set.
*/
public void setEndNodeID(String endNodeID) {
EndNodeID = endNodeID;
}
/**
* @return Returns the startNodeID.
*/
public String getStartNodeID() {
return StartNodeID;
}
/**
* @param startNodeID The startNodeID to set.
*/
public void setStartNodeID(String startNodeID) {
StartNodeID = startNodeID;
}
/**
* @return Returns the weight.
*/
public double getWeight() {
return Weight;
}
/**
* @param weight The weight to set.
*/
public void setWeight(double weight) {
Weight = weight;
}
}
//==========================================================================
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
import java.util.ArrayList;
/**
* @author 周振興
* @version 1.00
*/
public class Node {
private String iD;
private ArrayList edgeList;
public Node(String id) {
this.iD = id;
this.edgeList = new ArrayList();
}
/**
* @return Returns the edgeList.
*/
public ArrayList getEdgeList() {
return edgeList;
}
/**
* @param edgeList The edgeList to set.
*/
public void setEdgeList(ArrayList edgeList) {
this.edgeList = edgeList;
}
/**
* @return Returns the iD.
*/
public String getID() {
return iD;
}
/**
* @param id The iD to set.
*/
public void setID(String id) {
iD = id;
}
}
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
import java.util.ArrayList;
/**
* @author 周振興
* @version 1.00
*/
public class Node {
private String iD;
private ArrayList edgeList;
public Node(String id) {
this.iD = id;
this.edgeList = new ArrayList();
}
/**
* @return Returns the edgeList.
*/
public ArrayList getEdgeList() {
return edgeList;
}
/**
* @param edgeList The edgeList to set.
*/
public void setEdgeList(ArrayList edgeList) {
this.edgeList = edgeList;
}
/**
* @return Returns the iD.
*/
public String getID() {
return iD;
}
/**
* @param id The iD to set.
*/
public void setID(String id) {
iD = id;
}
}
//==========================================================================
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
import java.util.ArrayList;
/**
* @author 周振興
* @version 1.00
*/
public class PassedPath {
private String curNodeID;
private boolean beProcessed;
private double weight;
private ArrayList passedIDList;
public PassedPath(String ID) {
this.curNodeID = ID;
this.weight = Double.MAX_VALUE;
this.passedIDList = new ArrayList();
this.beProcessed = false;
}
/**
* @return Returns the beProcessed.
*/
public boolean isBeProcessed() {
return beProcessed;
}
/**
* @param beProcessed The beProcessed to set.
*/
public void setBeProcessed(boolean beProcessed) {
this.beProcessed = beProcessed;
}
/**
* @return Returns the curNodeID.
*/
public String getCurNodeID() {
return curNodeID;
}
/**
* @param curNodeID The curNodeID to set.
*/
public void setCurNodeID(String curNodeID) {
this.curNodeID = curNodeID;
}
/**
* @return Returns the passedIDList.
*/
public ArrayList getPassedIDList() {
return passedIDList;
}
/**
* @param passedIDList The passedIDList to set.
*/
public void setPassedIDList(ArrayList passedIDList) {
this.passedIDList = passedIDList;
}
/**
* @return Returns the weight.
*/
public double getWeight() {
return weight;
}
/**
* @param weight The weight to set.
*/
public void setWeight(double weight) {
this.weight = weight;
}
}
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
import java.util.ArrayList;
/**
* @author 周振興
* @version 1.00
*/
public class PassedPath {
private String curNodeID;
private boolean beProcessed;
private double weight;
private ArrayList passedIDList;
public PassedPath(String ID) {
this.curNodeID = ID;
this.weight = Double.MAX_VALUE;
this.passedIDList = new ArrayList();
this.beProcessed = false;
}
/**
* @return Returns the beProcessed.
*/
public boolean isBeProcessed() {
return beProcessed;
}
/**
* @param beProcessed The beProcessed to set.
*/
public void setBeProcessed(boolean beProcessed) {
this.beProcessed = beProcessed;
}
/**
* @return Returns the curNodeID.
*/
public String getCurNodeID() {
return curNodeID;
}
/**
* @param curNodeID The curNodeID to set.
*/
public void setCurNodeID(String curNodeID) {
this.curNodeID = curNodeID;
}
/**
* @return Returns the passedIDList.
*/
public ArrayList getPassedIDList() {
return passedIDList;
}
/**
* @param passedIDList The passedIDList to set.
*/
public void setPassedIDList(ArrayList passedIDList) {
this.passedIDList = passedIDList;
}
/**
* @return Returns the weight.
*/
public double getWeight() {
return weight;
}
/**
* @param weight The weight to set.
*/
public void setWeight(double weight) {
this.weight = weight;
}
}
//==========================================================================
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
import java.util.ArrayList;
import java.util.Hashtable;
/**
* @author 周振興
* @version 1.00
*/
public class PlanCourse {
private Hashtable htPassedPath;
public PlanCourse(ArrayList nodeList, String originID) throws Exception {
this.htPassedPath = new Hashtable();
Node originNode = null;
for (int i = 0; i < nodeList.size(); i++) {
Node node = (Node) nodeList.get(i);
if (node.getID() == originID) {
originNode = node;
} else {
PassedPath pPath = new PassedPath(node.getID());
this.htPassedPath.put(node.getID(), pPath);
}
}
if (originNode == null) {
throw new Exception("The origin node is not exist !");
}
this.InitializeWeight(originNode);
}
private void InitializeWeight(Node originNode) {
if ((originNode.getEdgeList() == null) || (originNode.getEdgeList().size() == 0)) {
return;
}
for (int i = 0; i < originNode.getEdgeList().size(); i++) {
Edge edge = (Edge) originNode.getEdgeList().get(i);
PassedPath pPath = getPassedPath(edge.EndNodeID);
if (pPath == null) {
continue;
}
pPath.getPassedIDList().add(originNode.getID());
pPath.setWeight(edge.getWeight());
}
}
public PassedPath getPassedPath(String nodeID) {
return (PassedPath) this.htPassedPath.get(nodeID);
}
}
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
import java.util.ArrayList;
import java.util.Hashtable;
/**
* @author 周振興
* @version 1.00
*/
public class PlanCourse {
private Hashtable htPassedPath;
public PlanCourse(ArrayList nodeList, String originID) throws Exception {
this.htPassedPath = new Hashtable();
Node originNode = null;
for (int i = 0; i < nodeList.size(); i++) {
Node node = (Node) nodeList.get(i);
if (node.getID() == originID) {
originNode = node;
} else {
PassedPath pPath = new PassedPath(node.getID());
this.htPassedPath.put(node.getID(), pPath);
}
}
if (originNode == null) {
throw new Exception("The origin node is not exist !");
}
this.InitializeWeight(originNode);
}
private void InitializeWeight(Node originNode) {
if ((originNode.getEdgeList() == null) || (originNode.getEdgeList().size() == 0)) {
return;
}
for (int i = 0; i < originNode.getEdgeList().size(); i++) {
Edge edge = (Edge) originNode.getEdgeList().get(i);
PassedPath pPath = getPassedPath(edge.EndNodeID);
if (pPath == null) {
continue;
}
pPath.getPassedIDList().add(originNode.getID());
pPath.setWeight(edge.getWeight());
}
}
public PassedPath getPassedPath(String nodeID) {
return (PassedPath) this.htPassedPath.get(nodeID);
}
}
//==========================================================================
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
import java.util.ArrayList;
/**
* @author 周振興
* @version 1.00
*/
public class RoutePlanner {
public RoutePlanner() {
}
public RoutePlanResult Paln(ArrayList nodeList, String originID, String destID) throws Exception {
PlanCourse planCourse = new PlanCourse(nodeList, originID);
Node curNode = this.GetMinWeightRudeNode(planCourse, nodeList, originID);
while (curNode != null) {
PassedPath curPath = planCourse.getPassedPath(curNode.getID());
for (int j = 0; j < curNode.getEdgeList().size(); j++) {
Edge edge = (Edge) curNode.getEdgeList().get(j);
PassedPath targetPath = planCourse.getPassedPath(edge.EndNodeID);
double tempWeight = curPath.getWeight() + edge.getWeight();
if (tempWeight < targetPath.getWeight()) {
targetPath.setWeight(tempWeight);
targetPath.getPassedIDList().clear();
for (int i = 0; i < curPath.getPassedIDList().size(); i++) {
targetPath.getPassedIDList().add(curPath.getPassedIDList().get(i).toString());
}
targetPath.getPassedIDList().add(curNode.getID());
}
}
planCourse.getPassedPath(curNode.getID()).setBeProcessed(true);
curNode = this.GetMinWeightRudeNode(planCourse, nodeList, originID);
}
return this.GetResult(planCourse, destID);
}
private RoutePlanResult GetResult(PlanCourse planCourse, String destID) {
PassedPath pPath = planCourse.getPassedPath(destID);
if (pPath.getWeight() == Integer.MAX_VALUE) {
RoutePlanResult result1 = new RoutePlanResult(null, Integer.MAX_VALUE);
return result1;
}
String[] passedNodeIDs = new String[pPath.getPassedIDList().size()];
for (int i = 0; i < passedNodeIDs.length; i++) {
passedNodeIDs[i] = pPath.getPassedIDList().get(i).toString();
}
RoutePlanResult result = new RoutePlanResult(passedNodeIDs, pPath.getWeight());
return result;
}
private Node GetMinWeightRudeNode(PlanCourse planCourse, ArrayList nodeList, String originID) {
double weight = Double.MAX_VALUE;
Node destNode = null;
for (int i = 0; i < nodeList.size(); i++) {
Node node = (Node) nodeList.get(i);
if (node.getID() == originID) {
continue;
}
PassedPath pPath = planCourse.getPassedPath(node.getID());
if (pPath.isBeProcessed()) {
continue;
}
if (pPath.getWeight() < weight) {
weight = pPath.getWeight();
destNode = node;
}
}
return destNode;
}
}
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
import java.util.ArrayList;
/**
* @author 周振興
* @version 1.00
*/
public class RoutePlanner {
public RoutePlanner() {
}
public RoutePlanResult Paln(ArrayList nodeList, String originID, String destID) throws Exception {
PlanCourse planCourse = new PlanCourse(nodeList, originID);
Node curNode = this.GetMinWeightRudeNode(planCourse, nodeList, originID);
while (curNode != null) {
PassedPath curPath = planCourse.getPassedPath(curNode.getID());
for (int j = 0; j < curNode.getEdgeList().size(); j++) {
Edge edge = (Edge) curNode.getEdgeList().get(j);
PassedPath targetPath = planCourse.getPassedPath(edge.EndNodeID);
double tempWeight = curPath.getWeight() + edge.getWeight();
if (tempWeight < targetPath.getWeight()) {
targetPath.setWeight(tempWeight);
targetPath.getPassedIDList().clear();
for (int i = 0; i < curPath.getPassedIDList().size(); i++) {
targetPath.getPassedIDList().add(curPath.getPassedIDList().get(i).toString());
}
targetPath.getPassedIDList().add(curNode.getID());
}
}
planCourse.getPassedPath(curNode.getID()).setBeProcessed(true);
curNode = this.GetMinWeightRudeNode(planCourse, nodeList, originID);
}
return this.GetResult(planCourse, destID);
}
private RoutePlanResult GetResult(PlanCourse planCourse, String destID) {
PassedPath pPath = planCourse.getPassedPath(destID);
if (pPath.getWeight() == Integer.MAX_VALUE) {
RoutePlanResult result1 = new RoutePlanResult(null, Integer.MAX_VALUE);
return result1;
}
String[] passedNodeIDs = new String[pPath.getPassedIDList().size()];
for (int i = 0; i < passedNodeIDs.length; i++) {
passedNodeIDs[i] = pPath.getPassedIDList().get(i).toString();
}
RoutePlanResult result = new RoutePlanResult(passedNodeIDs, pPath.getWeight());
return result;
}
private Node GetMinWeightRudeNode(PlanCourse planCourse, ArrayList nodeList, String originID) {
double weight = Double.MAX_VALUE;
Node destNode = null;
for (int i = 0; i < nodeList.size(); i++) {
Node node = (Node) nodeList.get(i);
if (node.getID() == originID) {
continue;
}
PassedPath pPath = planCourse.getPassedPath(node.getID());
if (pPath.isBeProcessed()) {
continue;
}
if (pPath.getWeight() < weight) {
weight = pPath.getWeight();
destNode = node;
}
}
return destNode;
}
}
//==========================================================================
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
/**
* @author 周振興
* @version 1.00
*/
public class RoutePlanResult {
private String[] passedNodeIDs;
private double weight;
public RoutePlanResult(String[] strings, double d) {
this.passedNodeIDs = strings;
this.weight = d;
}
/**
* @return Returns the passedNodeIDs.
*/
public String[] getPassedNodeIDs() {
return passedNodeIDs;
}
/**
* @param passedNodeIDs The passedNodeIDs to set.
*/
public void setPassedNodeIDs(String[] passedNodeIDs) {
this.passedNodeIDs = passedNodeIDs;
}
/**
* @return Returns the weight.
*/
public double getWeight() {
return weight;
}
/**
* @param weight The weight to set.
*/
public void setWeight(double weight) {
this.weight = weight;
}
}
// version 変更日 変更者 変更内容
//--------------------------------------------------------------------------
// 1.00 2006/01/31 周振興 新規作成
//**************************************************************************
package path;
/**
* @author 周振興
* @version 1.00
*/
public class RoutePlanResult {
private String[] passedNodeIDs;
private double weight;
public RoutePlanResult(String[] strings, double d) {
this.passedNodeIDs = strings;
this.weight = d;
}
/**
* @return Returns the passedNodeIDs.
*/
public String[] getPassedNodeIDs() {
return passedNodeIDs;
}
/**
* @param passedNodeIDs The passedNodeIDs to set.
*/
public void setPassedNodeIDs(String[] passedNodeIDs) {
this.passedNodeIDs = passedNodeIDs;
}
/**
* @return Returns the weight.
*/
public double getWeight() {
return weight;
}
/**
* @param weight The weight to set.
*/
public void setWeight(double weight) {
this.weight = weight;
}
}
嫌来无视,把c#代码转换成java代码
呵呵,也不知道对不对,给以后的各位提供一个方便
呵呵,也不知道对不对,给以后的各位提供一个方便
为什么没有初始化,和获得查询就结果的代码?
请回复qq:13448739
请回复qq:13448739
我知道如何初始化了阿
8过,我觉得用arraylist速度比较慢,建议斑竹修改。我准备修改一下哦
收下,谢谢斑竹
能否写个简单的初始化和保存结果的例子,谢谢
谢谢楼主,可以用了.
不知道是程序的问题,还是我构建的图有问题,我发现如果在图中存在一个或多个闭合的回路,该程序好像会出现错误,不知道笔者是否遇到过,应该如何解决呢?
请问我把楼主的代码录入之后,怎么不出现最短路经的结果呢
谢谢
谢谢
怎么才能初始化并取得结果阿?
@seawwy
你怎么初始化的阿?
你怎么初始化的阿?
函数public RoutePlanResult Paln(ArrayList nodeList ,string originID ,string destID) 有错误
应该在语句:PassedPath targetPath = planCourse[edge.EndNodeID] 前面加上
if(edge.EndNodeID==originID )
continue;
应该在语句:PassedPath targetPath = planCourse[edge.EndNodeID] 前面加上
if(edge.EndNodeID==originID )
continue;
public class RoutePlanResult
{
private string[] passedNodeIDs;
private double weight;
public RoutePlanResult(string[] strings, double d)
{
this.passedNodeIDs = strings;
this.weight = d;
}
/**
* @return Returns the passedNodeIDs.
*/
public string[] getPassedNodeIDs()
{
return passedNodeIDs;
}
/**
* @param passedNodeIDs The passedNodeIDs to set.
*/
public void setPassedNodeIDs(string[] passedNodeIDs)
{
this.passedNodeIDs = passedNodeIDs;
}
/**
* @return Returns the weight.
*/
public double getWeight()
{
return weight;
}
/**
* @param weight The weight to set.
*/
public void setWeight(double weight)
{
this.weight = weight;
}
}
{
private string[] passedNodeIDs;
private double weight;
public RoutePlanResult(string[] strings, double d)
{
this.passedNodeIDs = strings;
this.weight = d;
}
/**
* @return Returns the passedNodeIDs.
*/
public string[] getPassedNodeIDs()
{
return passedNodeIDs;
}
/**
* @param passedNodeIDs The passedNodeIDs to set.
*/
public void setPassedNodeIDs(string[] passedNodeIDs)
{
this.passedNodeIDs = passedNodeIDs;
}
/**
* @return Returns the weight.
*/
public double getWeight()
{
return weight;
}
/**
* @param weight The weight to set.
*/
public void setWeight(double weight)
{
this.weight = weight;
}
}
缺少一个类,补充如下
public class RoutePlanResult
{
private string[] passedNodeIDs;
private double weight;
public RoutePlanResult(string[] strings, double d)
{
this.passedNodeIDs = strings;
this.weight = d;
}
/**
* @return Returns the passedNodeIDs.
*/
public string[] getPassedNodeIDs()
{
return passedNodeIDs;
}
/**
* @param passedNodeIDs The passedNodeIDs to set.
*/
public void setPassedNodeIDs(string[] passedNodeIDs)
{
this.passedNodeIDs = passedNodeIDs;
}
/**
* @return Returns the weight.
*/
public double getWeight()
{
return weight;
}
/**
* @param weight The weight to set.
*/
public void setWeight(double weight)
{
this.weight = weight;
}
}
public class RoutePlanResult
{
private string[] passedNodeIDs;
private double weight;
public RoutePlanResult(string[] strings, double d)
{
this.passedNodeIDs = strings;
this.weight = d;
}
/**
* @return Returns the passedNodeIDs.
*/
public string[] getPassedNodeIDs()
{
return passedNodeIDs;
}
/**
* @param passedNodeIDs The passedNodeIDs to set.
*/
public void setPassedNodeIDs(string[] passedNodeIDs)
{
this.passedNodeIDs = passedNodeIDs;
}
/**
* @return Returns the weight.
*/
public double getWeight()
{
return weight;
}
/**
* @param weight The weight to set.
*/
public void setWeight(double weight)
{
this.weight = weight;
}
}
楼主,有个专业的问题想请问下,我现在想做个瓶颈路段的交通路径选择的编程,可是无从下手,希望楼主给个建议哈,有程序就更好了=。=
标签:
路径规划(最短路径)算法C#实现
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理