美文网首页
图的最小生成树

图的最小生成树

作者: mrjunwang | 来源:发表于2018-07-16 15:38 被阅读0次

关于图的几个概念定义:

连通图:在无向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该无向图为连通图。
强连通图:在有向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该有向图为强连通图。
连通网:在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权;权代表着连接连个顶点的代价,称这种连通图叫做连通网。
生成树:一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,但只有足以构成一棵树的n-1条边。一颗有n个顶点的生成树有且仅有n-1条边,如果生成树中再添加一条边,则必定成环。
最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。
1.Prim算法
假设最小生成树的顶点集合Vr,边的集合为Er.
1.初始化:从图G的顶点集合V中任意选择一个顶点加入到Vr.Er为空。
2.遍历Vr中的所有顶点,找到和他们相关联且权值最小的边(如果这条边的两个顶点均在Vr中,则跳过此边),将最小的边加入到Er中,相应的顶点加入到Vr中。
3.第2步一共做n-1次。

public Graph createMinTreeWithPrim(Graph g){
        
        Set<Node> nodes=g.nodes;
        Set<Node> minNodes=new HashSet<>();
        Set<Edge> minEdges=new HashSet<>();
        for(Node node:nodes){
            minNodes.add(node);
            //System.out.println("selected"+node.value);
            break;
        }
        
        for(int i=0;i<nodes.size()-1;i++){
            
            Edge minEdge=null;
            int minWeight=Integer.MAX_VALUE;
            for(Node n:minNodes){
                List<Edge> edges=n.getEdges();

                for(Edge e:edges){
                    if(minNodes.contains(e.start)&&minNodes.contains(e.end)){
                        continue;
                    }
                    if(e.weight<minWeight){
                        minWeight=e.weight;
                        minEdge=e;
                    }
                    
                    
                }
            }

            minEdges.add(minEdge);
            if(minNodes.contains(minEdge.start)){
                minNodes.add(minEdge.end);
            }
            else{
                minNodes.add(minEdge.start);
            }
            
        
        }
        ///System.out.println("minNodes"+minNodes.size());
        Graph graph=new Graph(minNodes,minEdges);
        return graph;
        
        
    }

2.Kruskal算法
并查集:
1)find(x):找到包含x元素的子集合
2)union(x,y):分别找到包含x,包含y的两个不想交的子集合的并集。

public class SetUtil<T> {

  Set<Set<T>>  set;
  
  public SetUtil(Set<Set<T>> s){
      this.set=s;
      
  }
  public Set find(T x){
      for(Set s:set){
          if(s.contains(x)){
              return s;
          }
      }
      return null;
  }
  
  
  public void union(T x,T y){
      Set sx=find(x);
      Set sy=find(y);
      if(sx!=null && sy!=null){
          sx.addAll(sy);
          set.remove(sy);
      }
      
  }
}

Kruskal算法思想
1.初始化,一个集合中S包含V个子集合。每个子集合中有一个元素,即图的一个顶点。
2.对图G的所有边进行排序,每次选出权值最小的边,在S查找这条边的开始节点和结束节点所属的子集,如果是同一个,则跳过。否则合并这两个子集。
3.第2步共做n-1次。

    /**
     * 
     * @param g
     * @return <p>
     *         Description:图的边权重排序,每次选权重最小且不会构成环路的边加进来。一共需要n-1次
     *         </p>
     */
    public Graph createMinTreeWithKruskal(Graph g) {
        Set<Edge> edges = g.edges;
        Set<Edge> minEdges = new HashSet<>();
        Set<Node> nodes = g.nodes;

        Set<Set<Node>> nodeSet = new HashSet<>();
        

        for(Node n:nodes){
            Set newSet=new HashSet<>();
            newSet.add(n);
            nodeSet.add(newSet);
            
        }
        SetUtil setUtil = new SetUtil(nodeSet);
        for (int i = 0; i < g.nodes.size() - 1; i++) {
            int minWeight = Integer.MAX_VALUE;
            Edge minEdge = null;

            for (Edge edge : edges) {
                if (edge.weight <= minWeight) {
                    
                    Set start = setUtil.find(edge.start);
                    Set end = setUtil.find(edge.end);
                    if (start.equals(end)) {
                        //System.out.println("skip"+edge.start.value+""+edge.end.value);
                        continue;
                    }
                    else{
                        minWeight = edge.weight;
                        minEdge = edge;
                    }

                }
            }
            
            setUtil.union(minEdge.start, minEdge.end);
            minEdges.add(minEdge);
                
            edges.remove(minEdge);

        }

        Graph minGraph = new Graph(nodes, minEdges);
        return minGraph;

    }
IMG_20180716_155130.jpg

相关文章

网友评论

      本文标题:图的最小生成树

      本文链接:https://www.haomeiwen.com/subject/rndbpftx.html