一个用Dijkstra算法实现的路由算法的java程序——4 MapCanvas类

import java.awt.*;

/**
 * 一块实现地图绘制的画布。此画布添加到地图显示窗口中。
 * @author Fe
 */
public class MapCanvas extends Canvas {
 GraphFromFile graph = null;
 /**
  * 图中结点的数目。
  */
 int nodeNum = 0;
 /**
  * 图的邻接表引用。
  */
 GraphAdjList graphAdjList[] = null;
 /**
  * 图中结点的坐标引用。
  */
 int nodePosition[][] = null;
 /**
  * 图中坐标的名称引用。
  */
 String nodeID[] = null;
 
 /**
  * 简单的调用父类的构造函数。
  */
 public MapCanvas(GraphFromFile g) {
  super();
  
  graph = g;
  nodeNum = graph.getNodeNum();
  graphAdjList = graph.getList();
  nodePosition = graph.getNodePosition();
  nodeID = graph.getNodeID();
 }
 
 /**
  * 重载的paint函数用于实现地图网格以及结点和边的具体绘制。
  */
 public void paint(Graphics g) {
  //地图周围的空白边框。
  final int BLANK_BORDER = 15;
  //每个结点的直径。
  final int POINT_DIAMETER = 10;
  //每个网格的宽度。
  int cellWidth = (int)((getSize().getWidth() - 2*BLANK_BORDER)/40);
  //每个网格的高度。
  int cellHeight = (int)((getSize().getHeight() - 2*BLANK_BORDER)/40);
  //地图网格区域的总宽度。(网格数为40)
  int graphWidthRange = cellWidth * 40;
  //地图网格区域的总高度。(网格数为40)
  int graphHeightRange = cellHeight * 40;
    
  //绘制灰色的地图网格。
  g.setColor(Color.GRAY);
  for (int i = BLANK_BORDER; i <= graphHeightRange + BLANK_BORDER; i += cellHeight) {
   g.drawLine(BLANK_BORDER, i, graphWidthRange + BLANK_BORDER, i);
  }
  for (int j = BLANK_BORDER; j <= graphWidthRange + BLANK_BORDER; j += cellWidth) {
   g.drawLine(j, BLANK_BORDER, j, graphHeightRange + BLANK_BORDER);
  }
  
  //将每个结点根据其坐标信息绘制在相应的网格点上。并在其旁绘制相应的结点名称。
  g.setColor(Color.BLACK);
  for (int i = 0; i < nodeNum; i++) {
   g.fillOval((nodePosition[i][0]*cellWidth - POINT_DIAMETER/2) + BLANK_BORDER, (nodePosition[i][1]*cellHeight - POINT_DIAMETER/2) + BLANK_BORDER, POINT_DIAMETER, POINT_DIAMETER);
   g.setColor(Color.BLUE);
   g.drawString(nodeID[i], (nodePosition[i][0]*cellWidth + (POINT_DIAMETER/2+2)) + BLANK_BORDER, (nodePosition[i][1]*cellHeight + POINT_DIAMETER/2) + BLANK_BORDER);
   g.setColor(Color.BLACK);
  }
  
  //根据邻接表的信息,在邻接结点之间连线,并在线中央绘制边权大小。
  for (int i = 0; i < nodeNum; i++) {
   NextAdjNode temp = null;
   //如果该结点有邻接结点,则绘制。
   if (graphAdjList[i] != null) {
    temp = graphAdjList[i].firstNode;
    
    while (temp != null) {
     g.drawLine(nodePosition[i][0]*cellWidth + BLANK_BORDER, nodePosition[i][1]*cellHeight + BLANK_BORDER,
       nodePosition[temp.nodeNum][0]*cellWidth + BLANK_BORDER, nodePosition[temp.nodeNum][1]*cellHeight + BLANK_BORDER);
     g.setColor(Color.RED);
     g.drawString("" + temp.edgeWeight,
        (nodePosition[i][0]*cellWidth + nodePosition[temp.nodeNum][0]*cellWidth)/2 + BLANK_BORDER,
        (nodePosition[i][1]*cellHeight + nodePosition[temp.nodeNum][1]*cellHeight)/2 + BLANK_BORDER);
     g.setColor(Color.BLACK);
     
     //通过链表的遍历,实现所有邻接结点间的连线。
     temp = temp.nextNode;
    }
   }
  }
  
  //如果需要对特定路径进行特殊颜色的绘制,则绘制。其中,是否绘制由主程序通过接口控制。
  if (drawSpecifiedPath) {
   drawPath(g, path, cellWidth, cellHeight, BLANK_BORDER);
  }
  
  if (drawSubGraph) {
   for (int i = 0; i < subGraph.length; i++) {
    drawPath(g, subGraph[i], cellWidth, cellHeight, BLANK_BORDER);
   }
  }
 }

 /**
  * 控制是否绘制特定路径的布尔变量。由主程序根据需要通过接口设置。
  */
 static boolean drawSpecifiedPath = false;
 /**
  * 需要绘制的特定路径的引用。
  */
 static int path[] = null;
 
 /**
  * 主程序通过此接口设置是否需要绘制特定的路径信息。
  * @param pa
  * 需要绘制的特定路径的引用
  * @param draw
  * 是否需要绘制 true为需要 false为不需要
  */
 public static void setDrawSpecifiedPath(int pa[], boolean draw) {
  path = pa;
  drawSpecifiedPath = draw;
 }
 
 static boolean drawSubGraph = false;
 static int subGraph[][] = null;
 public static void setDrawSubGraph(int gr[][], boolean draw) {
  subGraph = gr;
  drawSubGraph = draw;
 }
 
 /**
  * 在原地图的基础上,绘制一条特定的路径信息。在此程序中为两城市间的最短路径。
  * @param g
  * 由paint传过来的Graphics的引用
  * @param path
  * 两城市间的最短路径
  * @param cellWidth
  * 网格宽度
  * @param cellHeight
  * 网格高度
  * @param BLANK_BORDER
  * 空白边界宽度
  */
 private void drawPath(Graphics g, int path[], int cellWidth, int cellHeight, int BLANK_BORDER) {
  g.setColor(Color.GREEN);
  for (int i = 0; i < path.length-1; i++) {
   g.drawLine(nodePosition[path[i]][0]*cellWidth + BLANK_BORDER, nodePosition[path[i]][1]*cellHeight + BLANK_BORDER,
     nodePosition[path[i+1]][0]*cellWidth + BLANK_BORDER, nodePosition[path[i+1]][1]*cellHeight + BLANK_BORDER);
  }
 }
}

Inputs: [AorV] Either A or V where A is a NxN adjacency matrix, where A(I,J) is nonzero if and only if an edge connects point I to point J NOTE: Works for both symmetric and asymmetric A V is a Nx2 (or Nx3) matrix of x,y,(z) coordinates [xyCorE] Either xy or C or E (or E3) where xy is a Nx2 (or Nx3) matrix of x,y,(z) coordinates (equivalent to V) NOTE: only valid with A as the first input C is a NxN cost (perhaps distance) matrix, where C(I,J) contains the value of the cost to move from point I to point J NOTE: only valid with A as the first input E is a Px2 matrix containing a list of edge connections NOTE: only valid with V as the first input E3 is a Px3 matrix containing a list of edge connections in the first two columns and edge weights in the third column NOTE: only valid with V as the first input [SID] (optional) 1xL vector of starting points. If unspecified, the algorithm will calculate the minimal path from all N points to the finish point(s) (automatically sets SID = 1:N) [FID] (optional) 1xM vector of finish points. If unspecified, the algorithm will calculate the minimal path from the starting point(s) to all N points (automatically sets FID = 1:N) Outputs: [costs] is an LxM matrix of minimum cost values for the minimal paths [paths] is an LxM cell containing the shortest path arrays [showWaitbar] (optional) a scalar logical that initializes a waitbar if nonzero Note: If the inputs are [A,xy] or [V,E], the cost is assumed to be (and is calculated as) the point to point Euclidean distance If the inputs are [A,C] or [V,E3], the cost is obtained from either the C matrix or from the edge weights in the 3rd column of E3 Example: % Calculate the (all pairs) shortest distances and paths using [A,C] inputs n = 7; A = zeros(n); xy = 10*rand(n,2) tri = delaunay(xy(:,1),xy(:,2)); I = tri(:); J = tri(:,[2 3 1]); J = J(:); IJ = I + n*(J-1); A(IJ) = 1 a = (1:n); b = a(ones(n,1),:); C = round(reshape(sqrt(sum((xy(b,:) - xy(b',:)).^2,2)),n,n)) [costs,paths] = dijkstra(A,C) Example: % Calculate the shortest distance and path from point 3 to 5 n = 15; A = zeros(n); xy = 10*rand(n,2) tri = delaunay(xy(:,1),xy(:,2)); I = tri(:); J = tri(:,[2 3 1]); J = J(:); IJ = I + n*(J-1); A(IJ) = 1 [cost,path] = dijkstra(A,xy,3,5) gplot(A,xy,'b.:'); hold on; plot(xy(path,1),xy(path,2),'ro-','LineWidth',2) for k = 1:n, text(xy(k,1),xy(k,2),[' ' num2str(k)],'Color','k'); end Example: % Calculate the shortest distances and paths from the 3rd point to all the rest n = 7; V = 10*rand(n,2) I = delaunay(V(:,1),V(:,2)); J = I(:,[2 3 1]); E = [I(:) J(:)] [costs,paths] = dijkstra(V,E,3) Example: % Calculate the shortest distance and path from points [1 3 4] to [2 3 5 7] n = 7; V = 10*rand(n,2) I = delaunay(V(:,1),V(:,2)); J = I(:,[2 3 1]); E = [I(:) J(:)] [costs,paths] = dijkstra(V,E,[1 3 4],[2 3 5 7]) Revision Notes: (3/13/15) Previously, this code ignored edges that have a cost of zero, potentially producing an incorrect result when such a condition exists. I have solved this issue by using NaNs in the table rather than a sparse matrix of zeros.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值