我假设你可以在空间中找到一个在领土内的点,称之为Z。(由于你有几个城市,你可以选择一个平均城市位置作为中心。)
给定起点Z,我考虑生成一组从该点向外的光线,每个光线具有较小和较大的大小范围,并且随着数量的增加而增长以获得详细信息。我下面草拟了一个方案。尚未测试任何内容;随时提出建议。
每个光线由角度Theta表示,并具有原点Z。每个光线不是一个长度,而是具有两个相关的长度:Inside和Outside,我们将尝试使其收敛。Inside的初始值设置为0,外部设置为比可能的领土半径更大的值(“Horizon”);我们将缩小Outside,直到它在领土内部,并增加Inside,直到它不完全在领土外部,使用二进制搜索(log2 N是游戏空间的直径)。当端点扩散以获取领土边界细节时,我们还将增加光线的数量。最终结果应该是一组光线,它们在距离“spacing”不超过一定距离的情况下建立了领土边界的范围。
你可以从一个光线(theta=North(0),Inside=0,Outside=Horizon)开始。我们称这组光线为R。我们假设光线集R按theta排序,如果我们有来自R的光线r,则next(r)是排序集中的下一个光线,其中最后一个光线的next(r)是集合中的第一个光线。由于你知道城市位置,你可以使用城市作为Inside点来种植光线集。它应该任何一种方式都可以。
另外一个参数“threshold”为您提供答案的精度程度。
R = empty
add_to_R(0,0,Horizon)
repeat until done
done = true
for each ray r in R
guess = average(Inside(r),Outside(r))
if guess>threshold
then done = false
if interritory(Z+(Theta(r),guess))
then Inside(r)=guess
else Outside(r)=guess
for each ray r in R
if (distance(Inside(r),Inside(next(r)))> spacing
then add_to_R(average(Theta(r),Theta(next(r)),
min(Inside(r),Inside(next(r)),
max(Outside(r),Outside(next(r))
end
在你的最大领地直径范围内,运行成本应该是log2,乘数与领地周长和所选射线端点间距有关。这个方案并不完美;如果射线没有在半岛内取样,它将无法运行。如果半岛非常窄,则需要采集大量样本才能发现它们。或许你可以选择一个半岛最小宽度,并调整算法以确保当它最终找到收敛的射线时向外步进半岛宽度,以确保没有出错。