克鲁斯卡尔(Kruskal)

核心思想

假设连通网G=(V,E),令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),概述图中每个顶点自成一个连通分量。在E中选择代价最小的边,若该边依附的顶点分别在T中不同的连通分量上,则将此边加入到T中;否则,舍去此边而选择下一条代价最小的边。依此类推,直至T中所有顶点构成一个连通分量为止

理解:图中的每个顶点都是一个连通分量,每次去寻找权值最小的边,然后判断最小生成树加入这条边是否会形成环,意思就是如果在不同的连通分量中则可以加入,如果在想通的连通分量中则不可以合并因为会构成环,怎么去判断是否在同一个连通分量中,就是判断他们是否在一个集合中。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Kruskal
{
    
    
    public class Vertex
    {
    
    
        public object Data;
        public Vertex(object data)
        {
    
    
            this.Data = data;
        }
    }
    public class Edge
    {
    
    
        public int Start;
        public int End;
        public int Weight;
        public Edge(int start, int end, int weight)
        {
    
    
            this.Start = start;
            this.End = end;
            this.Weight = weight;
        }
    }
    public class Graph
    {
    
    
        public int VertexCount;
        public Edge[] Edges;
        public Vertex[] Vertexs;

        public Graph(Vertex[] vertexs,Edge[] edges)
        {
    
    
            this.Vertexs = vertexs;
            this.Edges = edges;
            this.VertexCount = vertexs.Length;
        }
        
        private static void SortEdges(Edge[] edges)
        {
    
    
            for (int i = 0; i < edges.Length-1; i++)
            {
    
    
                if (edges[i].Weight > edges[i+1].Weight)
                {
    
    
                    Edge t = edges[i];
                    edges[i] = edges[i + 1];
                    edges[i + 1] = t;
                }
            }
        }
        private static int Find(int[] Vertexs,int index)
        {
    
    
            while (Vertexs[index] > -1)
            {
    
    
                index = Vertexs[index];
            }
            return index;
        }
        public static void Kruskal(Graph graph)
        {
    
    
            //1.生成父亲数组用于判断是否在想通的连通分量中
            int[] parent = new int[graph.VertexCount];
            for (int i = 0; i < parent.Length; i++)
            {
    
    
                parent[i] = -1;
            }
            //2.对边进行排序
            SortEdges(graph.Edges);
            //3.判断是否在想通的连通分量中=是否构成回路(环)
            for (int i = 0; i < graph.Edges.Length; i++)
            {
    
    
                int startRoot = Find(parent, graph.Edges[i].Start);
                int endRoot = Find(parent, graph.Edges[i].End);
                if (startRoot != endRoot)
                {
    
    
                    parent[endRoot] = startRoot;
                    Debug.LogError("(" + graph.Edges[i].Start + "," + graph.Edges[i].End + ") ");
                }
            }
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Kruskal;
public class TestKruskal : MonoBehaviour
{
    
    
    Graph graph;
    void Start()
    {
    
    
        Vertex[] vertexs = GenerateVertex(9);
        Edge[] edges = GenerateEdges();
        graph = new Graph(vertexs, edges);
        Graph.Kruskal(graph);
    }
    private Vertex[] GenerateVertex(int len)
    {
    
    
        Vertex[] vertexs = new Vertex[len];
        for (int i = 0; i < len; i++)
        {
    
    
            vertexs[i] = new Vertex(i);
        }
        return vertexs;
    }
    private Edge[] GenerateEdges()
    {
    
    

        Edge edge0 = new Edge(0, 1, 10);
        Edge edge1 = new Edge(0, 5, 11);

        Edge edge2 = new Edge(1, 2, 18);
        Edge edge3 = new Edge(1, 6, 16);
        Edge edge4 = new Edge(1, 8, 12);

        Edge edge5 = new Edge(2, 3, 22);
        Edge edge6 = new Edge(2, 8, 8);

        Edge edge7 = new Edge(3, 4, 20);
        Edge edge8 = new Edge(3, 7, 16);
        Edge edge9 = new Edge(3, 8, 21);

        Edge edge10 = new Edge(4, 5, 26);
        Edge edge11 = new Edge(4, 7, 7);

        Edge edge12 = new Edge(5, 6, 17);
        Edge edge13 = new Edge(6, 7, 19);
        Edge edge14 = new Edge(6, 7, 19);
        Edge[] edges = {
    
     edge0, edge1, edge2, edge3, edge4, edge5, edge6, edge7, edge8, edge9, edge10, edge11, edge12, edge13, edge14 };
        return edges;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39691716/article/details/122170224