本文实例讲述了Java贪心算法之Prime算法原理与实现方法。分享给大家供大家参考,具体如下:
Prime算法:是一种穷举查找算法来从一个连通图中构造一棵最小生成树。利用始终找到与当前树中节点权重最小的边,找到节点,加到最小生成树的节点集合中,直至所有节点都包括其中,这样就构成了一棵最小生成树。prime在算法中属于贪心算法的一种,贪心算法还有:Kruskal、Dijkstra以及哈夫曼树及编码算法。
下面具体讲一下prime算法:
1、首先需要构造一颗最小生成树,以及两个节点之间的权重数组,在此我们用一个二维数组来代表这样一个连通图的形式。节点就是0~数组长度-1,10000代表节点本身,权重 >= 100代表两个节点不连通,反之连通。
构建连通图代码如下:
// 初始化连通图 public static void initGraph(int[][] graph, ArrayListpoints) { 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]; } } }
连通图的数组表示:
2、找到距离当前树中节点权重最小的边,开始节点随机产生,(算法的重点)!!!
// prime算法实现 public static int prime(int[][] graph, ArrayListpoints, int current) { String path = ""; ArrayList selectPoints = new ArrayList (); // 选中的点集合 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 linePoints = new ArrayList (); // 记录所有与已选中点相连的点 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 ) 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 removeFormPoints(ArrayList points, int mincostPoint) { List tempPoints = new ArrayList (); for(int i = 0; i < points.size(); i++) { if(points.get(i) != mincostPoint) { tempPoints.add(points.get(i)); } } return tempPoints; }
以下是算法实现过程的打印信息:
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
该算法只是个人的理解实现,若有其他想法或者建议,欢迎大家交流。
忍者必须死34399账号登录版 最新版v1.0.138v2.0.72
下载勇者秘境oppo版 安卓版v1.0.5
下载忍者必须死3一加版 最新版v1.0.138v2.0.72
下载绝世仙王官方正版 最新安卓版v1.0.49
下载Goat Simulator 3手机版 安卓版v1.0.8.2
Goat Simulator 3手机版是一个非常有趣的模拟游
Goat Simulator 3国际服 安卓版v1.0.8.2
Goat Simulator 3国际版是一个非常有趣的山羊模
烟花燃放模拟器中文版 2025最新版v1.0
烟花燃放模拟器是款仿真的烟花绽放模拟器类型单机小游戏,全方位
我的世界动漫世界 手机版v友y整合
我的世界动漫世界模组整合包是一款加入了动漫元素的素材整合包,
我的世界贝爷生存整合包 最新版v隔壁老王
我的世界MITE贝爷生存整合包是一款根据原版MC制作的魔改整