一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java實現單源最短路徑

java實現單源最短路徑

2021-07-10 15:18浮生若夢yoo Java教程

這篇文章主要為大家詳細介紹了java實現單源最短路徑,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文采用java實現單源最短路徑,并帶有略微詳細的注解,供大家參考,具體內容如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
package com.qf.greaph;
 
import java.util.arraylist;
import java.util.arrays;
import java.util.hashmap;
import java.util.map;
import java.util.map.entry;
 
/**
 * @author jiayoo
 * 7 / 30
 * dijkstra最短路徑算法是一種單源最短路徑
 * 本文采用的是鄰接表表示圖。
 *
 * 圖的表示: 1. 采用 arraylist 來儲存 圖的頂點
 *   2. 采用 map 來儲存 邊集 , map 可以 實現 一對多的關系, 因此能很好的實現鄰接表結構
 *   3. 采用arraylist的原因 是使 邊集有序 這樣, node 的里面 那個記錄距離的集合才能一一對應
 */
 
public class minpath {
 
  private static class graph{
    private arraylist<node1> nodes = new arraylist<>(); // 表示圖頂點 , 同時他也作為v集合
    private map<node1, arraylist<node1>> adjanode = new hashmap<>(); // 表示圖的邊
    private arraylist<node1> nodes1 ; // 表示s集合, 即存儲已經訪問的節點,
    private float[] minpath; //用來存儲源點到每個頂點的距離
    float min = float.max_value;
 
    /**
     * @param start
     * @param end
     * @param distance
     * 構建鄰接表。使之成為圖
     */
    public void addadjanode(node1 start, node1 end, float distance) {
 
      if (!nodes.contains(start)) {
        nodes.add(start);
      }
      if (!nodes.contains(end)) {
        nodes.add(end);
      }
      if (adjanode.containskey(start) && adjanode.get(start).contains(end)) {
        return ;
      }
 
      if (adjanode.containskey(start)) {
        adjanode.get(start).add(end);
      }else {
        arraylist<node1> node = new arraylist<node1>();
        node.add(end);
        adjanode.put(start, node);
      }
      start.distonext.add(distance);
    }
 
    /**
     * 將圖打印出來
     */
    public void pringraph() {
      if (nodes == null || adjanode == null) {
        system.out.println("圖為空");
        return ;
      }
 
      for (entry<node1, arraylist<node1>> entry : adjanode.entryset()) {
        system.out.println("頂點 : " + entry.getkey().name + " 鏈接頂點有: ");
        for(int i = 0; i < entry.getvalue().size(); i++) {
          system.out.print(entry.getvalue().get(i).name + " " + "距離是: " + entry.getkey().distonext.get(i) + ", ");
        }
        system.out.println();
      }
    }
 
 
    /**
     * 1.這個方法用于初始化s集合 及 初始化距離數組
     * 2. 設置源點, 并且將源點作為內容 初始化算法
     */
    public void findminpath() {
      node1 node1 = null; // 用來記錄列表里最小的點
      nodes1 = new arraylist<>(); // 存儲已經遍歷過的點
      minpath = new float[nodes.size()]; // 初始化距離數組
      int i;
      /*
       * 對最短路徑進行初始化, 設置源點到其他地方的值為無窮大
       * */
      for (i = 0; i < minpath.length; i++) {
        minpath[i] = float.max_value;
      }
      node1 node = nodes.get(0);
      nodes1.add(node); // 將源點加入 s 集合
      node.visited = true;
 
      arraylist<node1> n = adjanode.get(node); // 獲取到源點的邊集
      /*
       * 先對源節點進行初始化
       * 1. 對 距離數組進行初始化。
       * 2. 找到源點到某個距離最短的點, 并標記
       *
       * */
      for (i = 0; i < n.size(); i++) {
        minpath[n.get(i).id] = node.distonext.get(i); // 最短路徑記錄
        if (min > node.distonext.get(i)) {
          min = node.distonext.get(i);
          node1 = n.get(i); // 找到當前最短路徑
        }
      }
      this.process(node1, min);
    }
 
 
    private void process(node1 node, float distance ) {
      min = float.max_value; //作為標記
      node1 node1 = null; // 同樣記錄距離最短的點
      int i;
      arraylist<node1> n = adjanode.get(node); // 獲得邊集
      for (i = 0 ; i < n.size(); i++) {
        if (!n.get(i).visited) { // 這個邊集里的頂點不在 s 集合里
          if (minpath[n.get(i).id] == float.max_value) {
            minpath[n.get(i).id] = distance + node.distonext.get(i); // 源點到下一點的距離
          }else if (distance + node.distonext.get(i) < minpath[n.get(i).id] ) { //源點到該頂點的距離變小了, 則改變
            minpath[n.get(i).id] = distance + node.distonext.get(i); // 更新源點到下一個點的距離
          }
        }
      }
      /*
       * 這個for 用于找到 距離集合中 距離源點最近 且并未被訪問過的
       * 這個for 同時可以確保 該節點確實可到達
       * */
 
      for (i = 1; i < minpath.length; i++) {
        if (!nodes.get(i).visited) {
          if (min  > minpath[i] ) {
            min = minpath[i];
            node1 = nodes.get(i);
          }
        }
      }
      if (node1 != null) {
        node1.visited = true;
        process(node1, min); //源點到 當前的距離
      }else { // 說明此位置沒有后續節點, 或者 已經全部被訪問完了, 則到達此位置只需要加上此位置的值
 
      }     
    }
  }
 
  public static void main(string[] args) {
 
    node1 n1 = new node1(0,"a");
    node1 n2 = new node1(1,"b");
    node1 n3 = new node1(2,"c");
    node1 n4 = new node1(3,"d");
    node1 n5 = new node1(4,"e");
    node1 n6 = new node1(5,"f");
    graph gp = new graph();
    gp.addadjanode(n1, n2, 6);
    gp.addadjanode(n2, n1, 6);
    gp.addadjanode(n1, n3, 3);
    gp.addadjanode(n3, n1, 3);
 
 
    gp.addadjanode(n2, n3, 2);
    gp.addadjanode(n3, n2, 2);
    gp.addadjanode(n2, n4, 5);
    gp.addadjanode(n4, n2, 5);
 
    gp.addadjanode(n3, n4, 3);
    gp.addadjanode(n4, n3, 3);
    gp.addadjanode(n3, n5, 4);
    gp.addadjanode(n5, n3, 4);
 
    gp.addadjanode(n4, n5, 2);
    gp.addadjanode(n5, n4, 2);
    gp.addadjanode(n4, n6, 3);
    gp.addadjanode(n6, n4, 3);
 
    gp.addadjanode(n5, n6, 5);
    gp.addadjanode(n6, n5, 5);
 
    // 下面嘗試一下非連通圖
 
//   /**
//    *   權值: 1
//    *  a -----------b
//    * 權 | *
//    * 值 | *  權值: 3
//    * 2  |  *
//    *   c-----d
//    * 權值: 5
//    *
//    *
//    * */
//  
//   gp.addadjanode(n1, n2, 1);
//   gp.addadjanode(n2, n1, 1);
//  
//   gp.addadjanode(n1, n3, 2);
//   gp.addadjanode(n3, n1, 2);
//  
//   gp.addadjanode(n1, n4, 3);
//   gp.addadjanode(n4, n1, 3);
//  
//   gp.addadjanode(n3, n4, 5);
//   gp.addadjanode(n4, n3, 5);
    gp.pringraph();
    system.out.println("--------------------------------------------------------------------");
    system.out.println("此數組下標代表id,值代表從源點分別到各點的最短距離, a開始的下標是0, b、c、d等依次類推, 并且源點默認設置為id為零0的開始");
    gp.findminpath(); 
    system.out.println(arrays.tostring(gp.minpath));
 
  }
 
}
 
 
/**
 * 頂點類
 */
class node1{
  string name;
  boolean visited = false; // 訪問狀態。有效 減少原算法移除v集合中元素所花費的時間
  int id = -1; // 設置默認id為-1
  arraylist<float> distonext = new arraylist<>(); //這一點 到另外每一個點的距離
  public node1(int id, string name) {
    this.id = id;
    this.name = name;
  }
 
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/qq_40860649/article/details/81291681

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 免费观看国产大片资源视频 | 欧美日韩一区二区三区久久 | 嫩草在线观看视频 | 男人免费视频 | www.久久艹| 国产专区日韩精品欧美色 | 娇妻中日久久持久久 | 午夜在线观看视频 | chinese高中生gay男同 | 高清一区高清二区视频 | 射西西| 操尼姑| 国产成人免费片在线视频观看 | 亚洲网红精品大秀在线观看 | 欧美日韩国产最新一区二区 | 国产精品视频一区二区三区不卡 | 99在线在线视频免费视频观看 | 草莓视频丝瓜 | 欧美yw193.c㎝在线观看 | 日韩香蕉网 | 和老外3p爽粗大免费视频 | 亚洲第一网站免费视频 | 精久久 | 视频免费观看在线播放高清 | 暖暖高清日本在线 | 男人与雌性宠物交啪啪小说 | 大杳蕉在线影院在线播放 | 秘书在办公室疯狂被hd | 性姿势女人嗷嗷叫图片 | 出差上的少妇20p | 深夜激情网站 | 暖暖的免费观看高清视频韩国 | chinese特色video| 日产乱码卡1卡2卡三卡四在线 | 日韩天堂视频 | 亚洲国产第一 | 毛片在线免费观看网站 | 日本护士撒尿xxxxhd | 激情三级hd中文字幕 | 女人肮脏的交易中文字幕未删减版 | 欧美又黄又激烈真实床戏 |