예제 #1
0
  /**
   * 初始化起始点 <br>
   * 初始时,S只包含起点s;U包含除s外的其他顶点,且U中顶点的距离为"起点s到该顶点的距离" [例如,U中顶点v的距离为(s,v)的长度,然后s和v不相邻,则v的距离为∞]。
   *
   * @param source 起始节点的Id
   * @param map 全局地图
   * @param closeSet 已经关闭的节点列表
   * @return
   */
  @SuppressWarnings("unchecked")
  public Maps.Node<T> init(T source, Maps<T> map, Set<T> closeSet) {

    Map<T, Maps.Node<T>> nodeMap = map.getNodes();
    Maps.Node<T> startNode = nodeMap.get(source);
    // 将初始节点放到close
    close.add(startNode);
    // 将其他节点放到open
    for (Maps.Node<T> node : nodeMap.values()) {
      if (!closeSet.contains(node.getId()) && !node.getId().equals(source)) {
        this.open.add(node);
      }
    }

    // 初始路径
    T startNodeId = startNode.getId();
    for (Entry<Maps.Node<T>, Integer> entry : startNode.getChilds().entrySet()) {
      Maps.Node<T> node = entry.getKey();
      if (open.contains(node)) {
        T nodeId = node.getId();
        path.put(node, entry.getValue());
        pathInfo.put(nodeId, new ArrayList<T>(Arrays.asList(startNodeId, nodeId)));
      }
    }

    for (Maps.Node<T> node : nodeMap.values()) {
      if (open.contains(node) && !path.containsKey(node)) {
        path.put(node, Integer.MAX_VALUE);
        pathInfo.put(node.getId(), new ArrayList<T>(Arrays.asList(startNodeId)));
      }
    }
    this.startNode = startNode;
    this.map = map;
    return startNode;
  }
예제 #2
0
  /**
   * 递归Dijkstra
   *
   * @param start 已经选取的最近节点
   */
  protected void computePath(Maps.Node<T> start) {
    // 从U中选出"距离最短的顶点k",并将顶点k加入到S中;同时,从U中移除顶点k。
    Maps.Node<T> nearest = getShortestPath(start);
    if (nearest == null) {
      return;
    }
    // 更新U中各个顶点到起点s的距离。
    // 之所以更新U中顶点的距离,是由于上一步中确定了k是求出最短路径的顶点,从而可以利用k来更新其它顶点的距离;
    // 例如,(s,v)的距离可能大于(s,k)+(k,v)的距离。
    close.add(nearest);
    open.remove(nearest);
    // 已经找到结果
    if (nearest == this.targetNode) {
      return;
    }
    Map<Maps.Node<T>, Integer> childs = nearest.getChilds();
    for (Map.Entry<Maps.Node<T>, Integer> entry : childs.entrySet()) {
      Maps.Node<T> child = entry.getKey();
      if (open.contains(child)) { // 如果子节点在open中
        Integer newCompute = path.get(nearest) + entry.getValue();
        if (path.get(child) > newCompute) { // 之前设置的距离大于新计算出来的距离
          path.put(child, newCompute);

          List<T> path = new ArrayList<T>(pathInfo.get(nearest.getId()));
          path.add(child.getId());
          pathInfo.put(child.getId(), path);
        }
      }
    }
    //		computePath(start);// 重复执行自己,确保所有子节点被遍历
    computePath(nearest); // 向外一层层递归,直至所有顶点被遍历
  }