Я думаю, что эта не сгенерирует все возможные карты, но подойдет для большинства "разумных".
Диаграммы Вороного состоят из разбиения плоскости в соответствии с близостью к выбранным точкам. Вы можете увидеть примеры в ссылке на Википедию в заголовке.
Алгоритм:
1) Выберите набор случайных точек, больше или равный нужному количеству провинций. Если вы генерируете больше, чем нужно, вы гарантируете пустые места.
2) Запустить алгоритм Вороного (может описать его, если вам интересно, но его легко найти в Интернете)
3) Рассчитать площади получаемых полигонов
4) Убедитесь, что у вас достаточно областей с поверхностью> (минимально необходимая площадь). Если нет, перейдите к 1
5) Если вы сгенерировали больше случайных точек, чем нужно, выберите случайным образом набор полигонов, которые будут составлять каждую провинцию из областей с областью> (минимальная область)
6) Проверьте, имеют ли ваши полигоны площадь <(максимальная площадь). Если нет, вы должны уменьшить их. </p>
7) Для уменьшения площади каждого многоугольника
- Пока площадь> (максимальная площадь)
- Найти границу полигона
- Удалить случайную точку от границы многоугольника
Кстати, я написал эту программу в Mathematica , чтобы получить графики выше:
Clear["Global`*"];
Needs["ComputationalGeometry`"];
data2D = Table[{RandomReal[16], RandomReal[16]}, {10}]
convexhull = ConvexHull[data2D]
(delval = DelaunayTriangulation[data2D]) // Shallow[#, {5, 6}] &
b1 = {{0, 0}, {16, 0}, {16, 16}, {0, 16}};
{diagvert1, diagval1} = BoundedDiagram[b1, data2D, delval, convexhull];
Show[{Graphics[Join[{PointSize[Large]}, {Point@data2D}], Frame -> True]}]
Show[{Graphics@Point[data2D], DiagramPlot[data2D, diagvert1, diagval1]}]
Я включил код, чтобы показать, что алгоритм легко реализовать с помощью правильных инструментов.
Примечание: в описании алгоритма не упоминается, что ваши области состоят из квадратов ...
* * НТН тысяче сорок-девять