服务器之家

服务器之家 > 正文

Java贪心算法之Prime算法原理与实现方法详解

时间:2021-01-01 12:50     来源/作者:Mr.洛洛

本文实例讲述了Java贪心算法之Prime算法原理与实现方法。分享给大家供大家参考,具体如下:

Prime算法:是一种穷举查找算法来从一个连通图中构造一棵最小生成树。利用始终找到与当前树中节点权重最小的边,找到节点,加到最小生成树的节点集合中,直至所有节点都包括其中,这样就构成了一棵最小生成树。prime在算法中属于贪心算法的一种,贪心算法还有:Kruskal、Dijkstra以及哈夫曼树及编码算法。

下面具体讲一下prime算法:

1、首先需要构造一颗最小生成树,以及两个节点之间的权重数组,在此我们用一个二维数组来代表这样一个连通图的形式。节点就是0~数组长度-1,10000代表节点本身,权重 >= 100代表两个节点不连通,反之连通。

构建连通图代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 初始化连通图
public static void initGraph(int[][] graph, ArrayList<Integer> points) {
    for(int i = 0 ; i < graph.length; i++) {
      points.add(i);
      for(int j = 0; j < graph[i].length; j++) {
        if(i == j) {
          graph[i][j] = 10000;
        }else {
          int temp = (int)(Math.random() * 200 +1);
          graph[i][j] = temp; // 大于等于100不连通, 小于100连通
        }
        graph[j][i] = graph[i][j];
      }
    }
}

连通图的数组表示:

Java贪心算法之Prime算法原理与实现方法详解

2、找到距离当前树中节点权重最小的边,开始节点随机产生,(算法的重点)!!!

?
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
// prime算法实现
public static int prime(int[][] graph, ArrayList<Integer> points, int current) {
    String path = "";
    ArrayList<Integer> selectPoints = new ArrayList<Integer>(); // 选中的点集合
    int totalWeights = 0// 权重总和
    selectPoints.add(current); // 添加初始开始节点
    points.remove(current); // 从未选择的节点集合中删除被选中的节点
    path = "|" + current + "|";
    System.out.println("当前路径:" + path);
    System.out.println("当前已选中节点: " + selectPoints.toString());
    System.out.println("当前剩余节点: " + points.toString());
    System.out.println("当前总权重: " + totalWeights);
    // 循环找出最小权重的边 直至所有的点都被选中
    while(points.size() > 0) {
      // 遍历选中的点相连的边中权重最小的边记录下来
      int mincost = 0// 最小权重
      int mincostPoint = selectPoints.get(0); // 最小权重边对应的点
      List<Integer> linePoints = new ArrayList<Integer>();  // 记录所有与已选中点相连的点
      for(int i = 0 ; i < selectPoints.size(); i++) {
        for(int j = 0; j < points.size(); j++) {
          int startPoint = selectPoints.get(i); // 起点
          int endPoint = points.get(j); // 终点
          // 两点是相连的
          if(graph[startPoint][endPoint] != 10000 && graph[startPoint][endPoint] < 100) {
            // 将和已选中点连通的点加入连通集合
            linePoints.add(points.get(j));
            if(linePoints.size() == 1) {
              // 将第一个连通的边的权重赋值为最小权重
              mincost = graph[startPoint][linePoints.get(0)];
              // 最小权重相连的点
              mincostPoint = endPoint;
            }else {
              // 与当前的最小权重比较
              if(graph[startPoint][endPoint] < mincost) {
                // 最小权重相连的点
                mincost = graph[startPoint][endPoint];
                mincostPoint = endPoint;
              }
            }
          }
        }
      }
      if(mincost != 0) { // 证明是找到了相连的点
        selectPoints.add(mincostPoint);   // 添加点
        points = (ArrayList<Integer>) removeFormPoints(points, mincostPoint);
        // 权重增加
        totalWeights += mincost;
        path += " ---" + mincost + "--- |" + mincostPoint + "|";
        System.out.println("当前路径:" + path);
      }else {
        System.out.println("不连通");
        return 0;
      }
      // 打印当前所选中的最小权重边对应的点
      System.out.println("当前已选中节点: " + selectPoints.toString());
      System.out.println("当前剩余节点: " + points.toString());
      System.out.println("当前总权重: " + totalWeights);
    }
    System.out.println("总路径:" + path);
    // 返回总权重
    return totalWeights;
}
// 删除剩余节点中的相连通的最小权重的节点的方法(就是将该节点加入最小生成树中)
public static List<Integer> removeFormPoints(ArrayList<Integer> points, int mincostPoint) {
    List<Integer> tempPoints = new ArrayList<Integer>();
    for(int i = 0; i < points.size(); i++) {
      if(points.get(i) != mincostPoint) {
        tempPoints.add(points.get(i));
      }
    }
    return tempPoints;
}

以下是算法实现过程的打印信息:

?
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
10000  101 72 100 146
101 10000  67 64 11
72 67 10000  13 79
100 64 13 10000  111
146 11 79 111 10000
开始所有节点集:[0, 1, 2, 3, 4]
开始节点:1
当前路径:|1|
当前已选中节点: [1]
当前剩余节点: [0, 2, 3, 4]
当前总权重: 0
当前路径:|1| ---11--- |4|
当前已选中节点: [1, 4]
当前剩余节点: [0, 2, 3]
当前总权重: 11
当前路径:|1| ---11--- |4| ---64--- |3|
当前已选中节点: [1, 4, 3]
当前剩余节点: [0, 2]
当前总权重: 75
当前路径:|1| ---11--- |4| ---64--- |3| ---13--- |2|
当前已选中节点: [1, 4, 3, 2]
当前剩余节点: [0]
当前总权重: 88
当前路径:|1| ---11--- |4| ---64--- |3| ---13--- |2| ---72--- |0|
当前已选中节点: [1, 4, 3, 2, 0]
当前剩余节点: []
当前总权重: 160
总路径:|1| ---11--- |4| ---64--- |3| ---13--- |2| ---72--- |0|
总权重:160

该算法只是个人的理解实现,若有其他想法或者建议,欢迎大家交流。

希望本文所述对大家java程序设计有所帮助。

原文链接:http://blog.csdn.net/u014455765/article/details/50217867

相关文章

热门资讯

2022年最旺的微信头像大全 微信头像2022年最新版图片
2022年最旺的微信头像大全 微信头像2022年最新版图片 2022-01-10
蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整
蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整 2021-08-24
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
暖暖日本高清免费中文 暖暖在线观看免费完整版韩国
暖暖日本高清免费中文 暖暖在线观看免费完整版韩国 2021-05-08
返回顶部

675
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40