/// <summary>
        /// Runs Karger's algorithm on a graph (that respresents a list of polygons) once, which splits a cluster of polygons into two random parts. https://en.wikipedia.org/wiki/Karger%27s_algorithm
        /// Returns two new lists with the splitted continents
        /// </summary>
        private static KargerGraph SplitClusterOnce(List<GraphPolygon> cluster)
        {
            // First we need to turn the cluster into a Karger graph (which is just a regular unweighted undirected graph), where the nodes contain information about which polygons they contain
            KargerGraph graph = new KargerGraph();
            Dictionary<GraphPolygon, KargerGraphVertex> vertices = new Dictionary<GraphPolygon, KargerGraphVertex>();
            foreach (GraphPolygon poly in cluster)
            {
                KargerGraphVertex vertex = new KargerGraphVertex(poly);
                graph.Vertices.Add(vertex);
                vertices.Add(poly, vertex);
            }
            List<GraphPolygon> visitedPolygons = new List<GraphPolygon>();
            foreach(GraphPolygon poly in cluster)
            {
                visitedPolygons.Add(poly);
                foreach(GraphPolygon neighbourPoly in poly.LandNeighbours.Where(x => cluster.Contains(x) && !visitedPolygons.Contains(x)))
                {
                    KargerGraphEdge edge = new KargerGraphEdge(vertices[poly], vertices[neighbourPoly]);
                    graph.Edges.Add(edge);
                    vertices[poly].Edges.Add(edge);
                    vertices[neighbourPoly].Edges.Add(edge);
                }
            }

            // Debug graph
            /*
            foreach(KargerGraphEdge edge in graph.Edges)
            {
                Vector2 from = edge.FromVertex.ContainedPolygons[0].CenterPoi;
                Vector2 to = edge.ToVertex.ContainedPolygons[0].CenterPoi;
                Debug.DrawLine(new Vector3(from.x, 0f, from.y), new Vector3(to.x, 0f, to.y), Color.red, 30);
            }
            */

            // Then collapse edges in the graph until only 2 vertices are left
            while(graph.Vertices.Count > 2)
            {
                KargerGraphEdge randomEdge = graph.Edges[Random.Range(0, graph.Edges.Count)];
                CollapseEdge(graph, randomEdge);
            }

            graph.CutSize = graph.Vertices[0].Edges.Count;

            return graph;
        }
Example #2
0
 public KargerGraphEdge(KargerGraphVertex fromVertex, KargerGraphVertex toVertex)
 {
     FromVertex = fromVertex;
     ToVertex   = toVertex;
 }