- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
考虑一个 r 行大小和 c 列大小的矩阵例如,给定 r = 19 和 c =11,我们将有一个包含 209 个元素的矩阵。所有元素的赋值为 0。因此我们有一个包含 0 的大矩阵。
给定以下 6 个“区域”Area1:31个元素Area2:35个元素Area3:35个元素Area4:37个元素Area5:32个元素Area6:39个元素
将所有面积元素加起来为 209,因此它们填满了整个矩阵。
是否有一种算法可以用这些区域中的每一个填充矩阵并将元素的值设置为区域名称?我需要的实际上不是设置部分,而是找到一个元素及其附近的元素的算法部分。
矩阵区域应该看起来像...比方说世界地图上的国家领土。所以我们不能在矩阵的左边有“area1”元素,然后在右边有其他区域。这些区域应该被压缩,具有接管矩阵元素时形成的随机“形状”。
基本上,为了更容易理解,我把它想象成在给定大小 (209) 的 map 上创建给定大小的随机区域。
有人可以推荐任何现有算法吗?或者任何方法?
编辑:6 个区域(基于给定的示例)填满了整个空间。不应留下任何背景元素(0 值元素)。我们示例中的 6 个区域应完全填充 209 个元素。
最佳答案
为了保持一些随机性,我这样处理这个问题:
为每个领土生成种子起点
简单地计算每个地区的随机起点,并限制任何 2 个起点之间必须至少有一些定义的最小距离。这将提供一些增长空间,因此结果看起来更好。
尽你所能种植每颗种子
简单地迭代扩大每个区域,直到没有间隙(忽略所需的区域大小)
更正尺寸
所以简单地占领领土i=1
并从任何邻近地区放大/缩小它们j>i
.然后处理i=2
...完成后按降序执行相同的操作,因此占据领土i=n
并从任何邻居放大/缩小j<i
.
循环整个过程,直到领土具有正确的大小
验证
bullet #3 可以将一些领土划分为非结果区域,我怀疑这是不受欢迎的。因此,检测到这一点,如果案件再次产生这整个事情。
要仅针对每个区域进行检测,请找到其第一个有效单元格并进行洪水填充计算该领土有多大。如果大小不匹配,领土已经划分,你应该重新生成。
如果所有地区的大小都匹配,那么 map 就是相关的,你就完成了
此处预览#1、#2、#3:
表格标题中的数字是领土 actual size - wanted size
第一个数字是差距然后进入领土1,2,3 ...
还有我的 C++ 实现:
//---------------------------------------------------------------------------
// generator properties
const int n=7; // teritories+1
const int mx=19; // map size
const int my=11;
const int siz[n]={ 0,31,35,35,37,32,39 }; // teritory sizes (first is bordrer)
const int mindist=5; // min distance between teritory seed points
int map[mx][my]; // map 0 means no teritory else it is teritory ID
// rendering properties
const int grid=16; // grid size [pixels]
const DWORD col[n]= // teritory color table
{
0x00000000, // border (unused)
0x00FF0000, // territory 1
0x0000FF00, // territory 2
0x000000FF, // territory 3
0x00FFFF00, // territory 4
0x0000FFFF, // territory 5
0x00FF00FF, // territory 6
};
//---------------------------------------------------------------------------
void map_generate()
{
int x,y,xx,yy,i,j,e;
int cnt[n]; // generated teritory size
int seedx[n]; // start position for teritory
int seedy[n];
// AnsiString s="";
// s+=AnsiString().sprintf("Seed: %X |",RandSeed);
for (;;)
{
// clear map
cnt[0]=mx*my;
for (x=0;x<mx;x++)
for (y=0;y<my;y++)
map[x][y]=0;
// start position
for (i=1;i<n;)
{
// ranom position
seedx[i]=Random(mx);
seedy[i]=Random(my);
// find closest seed point x = distance to it
for (x=mx+my,j=1;j<i;j++)
{
y=abs(seedx[i]-seedx[j])+abs(seedy[i]-seedy[j]);
if (x>y) x=y;
}
// if OK use as seed point else repeat the whole thing again...
if (x>mindist)
{
map[seedx[i]][seedy[i]]=i;
cnt[i]=1; cnt[0]--; i++;
}
}
// un bounded growth fill (can exceeding area)
for (e=1;e;)
{
e=0;
for (x= 1;x<mx;x++) for (y=0;y<my;y++) { i=map[x][y]; if (i>0){ x--; if (map[x][y]==0) { map[x][y]=i; cnt[i]++; cnt[0]--; e=1; } x++; }}
for (x=mx-2;x>=0;x--) for (y=0;y<my;y++) { i=map[x][y]; if (i>0){ x++; if (map[x][y]==0) { map[x][y]=i; cnt[i]++; cnt[0]--; e=1; } x--; }}
for (x=0;x<mx;x++) for (y= 1;y<my;y++) { i=map[x][y]; if (i>0){ y--; if (map[x][y]==0) { map[x][y]=i; cnt[i]++; cnt[0]--; e=1; } y++; }}
for (x=0;x<mx;x++) for (y=my-2;y>=0;y--) { i=map[x][y]; if (i>0){ y++; if (map[x][y]==0) { map[x][y]=i; cnt[i]++; cnt[0]--; e=1; } y--; }}
}
// correct inequalities cnt[] vs. siz[]
for (;;)
{
// stop if all counts are matching
for (i=1;i<n;i++) if (cnt[i]!=siz[i]) { i=-1; break; } if (i>=0) break;
// growth i from any neighbor j>i
for (i=1;i<n;i++)
for (e=1;(e)&&(cnt[i]<siz[i]);)
{
e=0;
for (x= 1;x<mx;x++) for (y=0;y<my;y++) if ((i==map[x][y])&&(cnt[i]<siz[i])){ x--; j=map[x][y]; if ((i<j)&&(cnt[j]>1)){ map[x][y]=i; cnt[i]++; cnt[j]--; e=1; } x++; }
for (x=mx-2;x>=0;x--) for (y=0;y<my;y++) if ((i==map[x][y])&&(cnt[i]<siz[i])){ x++; j=map[x][y]; if ((i<j)&&(cnt[j]>1)){ map[x][y]=i; cnt[i]++; cnt[j]--; e=1; } x--; }
for (x=0;x<mx;x++) for (y= 1;y<my;y++) if ((i==map[x][y])&&(cnt[i]<siz[i])){ y--; j=map[x][y]; if ((i<j)&&(cnt[j]>1)){ map[x][y]=i; cnt[i]++; cnt[j]--; e=1; } y++; }
for (x=0;x<mx;x++) for (y=my-2;y>=0;y--) if ((i==map[x][y])&&(cnt[i]<siz[i])){ y++; j=map[x][y]; if ((i<j)&&(cnt[j]>1)){ map[x][y]=i; cnt[i]++; cnt[j]--; e=1; } y--; }
}
// shrink i from any neighbor j>i
for (i=1;i<n;i++)
for (e=1;(e)&&(cnt[i]>siz[i]);)
{
e=0;
for (x= 1;x<mx;x++) for (y=0;y<my;y++) if ((i==map[x][y])&&(cnt[i]>siz[i])){ x--; j=map[x][y]; if (i<j) { map[x+1][y]=j; cnt[j]++; cnt[i]--; e=1; } x++; }
for (x=mx-2;x>=0;x--) for (y=0;y<my;y++) if ((i==map[x][y])&&(cnt[i]>siz[i])){ x++; j=map[x][y]; if (i<j) { map[x-1][y]=j; cnt[j]++; cnt[i]--; e=1; } x--; }
for (x=0;x<mx;x++) for (y= 1;y<my;y++) if ((i==map[x][y])&&(cnt[i]>siz[i])){ y--; j=map[x][y]; if (i<j) { map[x][y+1]=j; cnt[j]++; cnt[i]--; e=1; } y++; }
for (x=0;x<mx;x++) for (y=my-2;y>=0;y--) if ((i==map[x][y])&&(cnt[i]>siz[i])){ y++; j=map[x][y]; if (i<j) { map[x][y-1]=j; cnt[j]++; cnt[i]--; e=1; } y--; }
}
// stop if all counts are matching
for (i=1;i<n;i++) if (cnt[i]!=siz[i]) { i=-1; break; } if (i>=0) break;
// growth i from any neighbor j<i
for (i=n-1;i>0;i--)
for (e=1;(e)&&(cnt[i]<siz[i]);)
{
e=0;
for (x= 1;x<mx;x++) for (y=0;y<my;y++) if ((i==map[x][y])&&(cnt[i]<siz[i])){ x--; j=map[x][y]; if ((i>j)&&(cnt[j]>1)){ map[x][y]=i; cnt[i]++; cnt[j]--; e=1; } x++; }
for (x=mx-2;x>=0;x--) for (y=0;y<my;y++) if ((i==map[x][y])&&(cnt[i]<siz[i])){ x++; j=map[x][y]; if ((i>j)&&(cnt[j]>1)){ map[x][y]=i; cnt[i]++; cnt[j]--; e=1; } x--; }
for (x=0;x<mx;x++) for (y= 1;y<my;y++) if ((i==map[x][y])&&(cnt[i]<siz[i])){ y--; j=map[x][y]; if ((i>j)&&(cnt[j]>1)){ map[x][y]=i; cnt[i]++; cnt[j]--; e=1; } y++; }
for (x=0;x<mx;x++) for (y=my-2;y>=0;y--) if ((i==map[x][y])&&(cnt[i]<siz[i])){ y++; j=map[x][y]; if ((i>j)&&(cnt[j]>1)){ map[x][y]=i; cnt[i]++; cnt[j]--; e=1; } y--; }
}
// shrink i from any neighbor j<i
for (i=n-1;i>0;i--)
for (e=1;(e)&&(cnt[i]>siz[i]);)
{
e=0;
for (x= 1;x<mx;x++) for (y=0;y<my;y++) if ((i==map[x][y])&&(cnt[i]>siz[i])){ x--; j=map[x][y]; if (i>j) { map[x+1][y]=j; cnt[j]++; cnt[i]--; e=1; } x++; }
for (x=mx-2;x>=0;x--) for (y=0;y<my;y++) if ((i==map[x][y])&&(cnt[i]>siz[i])){ x++; j=map[x][y]; if (i>j) { map[x-1][y]=j; cnt[j]++; cnt[i]--; e=1; } x--; }
for (x=0;x<mx;x++) for (y= 1;y<my;y++) if ((i==map[x][y])&&(cnt[i]>siz[i])){ y--; j=map[x][y]; if (i>j) { map[x][y+1]=j; cnt[j]++; cnt[i]--; e=1; } y++; }
for (x=0;x<mx;x++) for (y=my-2;y>=0;y--) if ((i==map[x][y])&&(cnt[i]>siz[i])){ y++; j=map[x][y]; if (i>j) { map[x][y-1]=j; cnt[j]++; cnt[i]--; e=1; } y--; }
}
}
// test if teritories are not divided and regenerate if needed
for (xx=0,i=1;i<n;i++)
{
// clear temp bit
for (x=0;x<mx;x++)
for (y=0;y<my;y++)
map[x][y]&=65535;
// find first occurence
j=0;
for (x=0;x<mx;x++)
for (y=0;y<my;y++)
if (map[x][y]==i) { map[x][y]|=65536; j=1; x=mx; y=my; }
if (!j) { xx=1; break; } // teritory not found
// growth fill count into j
for (e=1;e;)
for (e=0,x=0;x<mx;x++)
for ( y=0;y<my;y++)
if (map[x][y]==i)
{
yy=0;
if ((x> 0)&&(map[x-1][y]>=65536)) yy=1;
if ((x<mx-1)&&(map[x+1][y]>=65536)) yy=1;
if ((y> 0)&&(map[x][y-1]>=65536)) yy=1;
if ((y<my-1)&&(map[x][y+1]>=65536)) yy=1;
if (yy){ j++; map[x][y]|=65536; e=1; }
}
if (j!=siz[i]) { xx=1; break; } // teritory incorrect size
}
if (xx) continue; // regenerate again
// clear temp bit
for (x=0;x<mx;x++)
for (y=0;y<my;y++)
map[x][y]&=65535;
break; // al OK so stop
}
// for (i=0;i<n;i++) { s+=cnt[i]-siz[i]; s+=" "; }
// Main->Caption=s;
}
//---------------------------------------------------------------------------
代码没有优化以尽可能保持简单易懂...(可以重新编码以更快)。
关于algorithm - 有没有一种算法可以随机填充这样的矩阵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43629968/
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
在现代 IDE 中,有一个键盘快捷键可以通过键入文件名称来打开文件,而无需将手放在鼠标上。例如: Eclipse:Cmd|Ctrl + Shift + R -> 打开资源 IntelliJ:Cmd|C
有什么东西会等待事件发生(我正在等待的是 WebBrowser.DocumentCompleted),然后执行代码吗?像这样: If (WebBrowser.DocumentCompleted) 不会
我使用 PHP Minify,它很棒。但我的问题是,是否有任何 PHP 插件或其他东西可以自动检测 javascript/css 代码并自动缩小它?谢谢。 最佳答案 Javascript 压缩器? 看
有没有一种语言,类似什么CoffeeScript是JavaScript,编译成windows batch|cmd|command line的语言? 我指的cmd版本是基于NT的,尤其是XP sp3及以
我知道我可以 ,但是,我真的宁愿有一个任务,我可以从任何可以使用所有(或至少大部分)属性的操作系统调用 copy ,但这并没有消除 unix 上的权限。 我想知道是否已经有解决方案,或者我必须自己编
我正在使用 Vuejs(不使用 jQuery)开发一个项目,该项目需要像 jvectormap 这样的 map 但正如我所说,我没有使用 jQuery,那么是否有任何其他库可以在不使用 jQuery
想要进行一个简单的民意调查,甚至不需要基于 cookie,我不在乎投了多少票。有没有类似的插件或者简单的东西? 最佳答案 这是一个有用的教程 - 让我知道它是否适合您 using jQuery to
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
var FileBuff: TBytes; Pattern: TBytes; begin FileBuff := filetobytes(filename); Result := Co
我想要一个 vqmod xml 文件来添加一次上传多个图像的功能。身边有这样的事吗? 编辑:Opencart版本:2.1.0.1 最佳答案 最后我写了一个xml来添加到opencart 2.1.0.1
所以考虑这样的函数: public void setTemperature(double newTemperatureValue, TemperatureUnit unit) 其中Temperatur
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我是 ggplot2 的新手,一直在尝试找到一个全面的美学列表。我想我理解它们的目的,但很难知道哪些可以在各种情况下使用(主要是几何图形?)。 Hadley 的网站偶尔会在各个几何图形的页面上列出可用
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
是否有任何 PHP 函数可以将整数转换为十万和千万? 900800 -> 9,00,800 500800 -> 5,00,800 最佳答案 由于您已在问题标签中添加了 Yii,因此您可以按照 Yii
使用 Clojure 一段时间后,我积累了一些关于它的惰性的知识。我知道诸如map之类的常用API是否是惰性的。然而,当我开始使用一个不熟悉的API(例如with-open)时,我仍然感到怀疑。 是否
我的项目需要一个像 AvalonDock 这样的对接系统,但它的最后一次更新似乎是在 2013 年 6 月。是否有更多...积极开发的东西可以代替它? 最佳答案 AvalonDock 实际上相当成熟并
我正在寻找一个可以逆转 clojure 打嗝的函数 所以 turns into [:html] 等等 根据@kotarak的回答,这现在对我有用: (use 'net.cgrand.enliv
我是一名优秀的程序员,十分优秀!