Algorithm 矩形定位算法

Algorithm 矩形定位算法,algorithm,Algorithm,我有矩形和网格布局,这些矩形的宽度和高度是相同的。因此,布局将矩形的位置与下图类似 这就是问题所在:如果我的矩形的宽度和高度大小不同,那么布局的算法是什么以紧凑的方式放置矩形的位置 终于有时间回答这个问题了,下面是我的垃圾箱代码: //--------------------------------------------------------------------------- //---矩形箱包类版本:1.00-------------------------------------

我有矩形和网格布局,这些矩形的宽度和高度是相同的。因此,布局将矩形的位置与下图类似

这就是问题所在:如果我的矩形的宽度和高度大小不同,那么布局的算法是什么以紧凑的方式放置矩形的位置


终于有时间回答这个问题了,下面是我的垃圾箱代码:

//---------------------------------------------------------------------------
//---矩形箱包类版本:1.00-------------------------------------
//---------------------------------------------------------------------------
常数双包无停止=1.0e+300;
类binpack_rec
{
公众:
struct{double x0,y0,xs,ys;{u rec(){x0=0.0;y0=0.0;xs=0.0;};{u rec({u rec&a){*this=a;};~{u rec(){};};{u rec operator=(const}rec a){*this=*a;返回this;};/*{u rec operator=(const};};/*;
结构{double-xs;int-i0,i1;{u-lin(){xs=0.0;i0=0;i1=0;};{u-lin({u-lin&a){*this=a;};~{u-lin(){};{u-lin*运算符=(const-lin*a){*this=*a;返回此;};/*{u-lin运算符=(const-lin a){…复制…返回此;*/};
_rec*rec;//矩形rec[N]
_lin*lin;//记录lin的行块[n]
int*ix,*on,n,n;//ix[n]索引已排序,on[n]是否使用矩形rec[ix[i]],n行块数,n个矩形数
binpack_rec(){rec=NULL;ix=NULL;on=NULL;N=0;}
~binpack_rec(){u free();}
void _free()//释放内存
{
n=0;n=0;
if(rec)delete[]rec;rec=NULL;
如果(lin)删除[]lin;lin=NULL;
如果(ix)删除[]ix;ix=NULL;
如果(on)删除[]on;on=NULL;
}
void _alloc(int _N)//为N个矩形分配空间
{
如果(_N==N)返回;
_自由();
如果(_Ny0=y;on[j]=0;
l->xs-=r->xs+w;
e=1;
}
}
打破
}
//更新已用记录
如果(yyys)yy=r->y;
r->x0=x;x+=r->xs+w;
r->y0=y;在[k]=0;
l->xs-=r->xs+w;
e=1;
}
if(e)//如果使用任何矩形
{
l->xs+=w;//添加一个空格(用于第一个矩形)
y+=yy+w;//将y更新到下一行
打破
}
}
}
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
用法:

binpack_rec bp_rec;
bp_rec.genere_random(N,x0,x1,y0,y1);        // genere N random rectangles with sizes (x0..x1),(y0..y1)
bp_rec.binpack(x0,y0,xs,w,acc); // compute positions for rectangles where: x0,y0-page start, xs-page size, w-space between rectangles, acc-acuracy for same Y-size

bp_rec.rec[0..(bp_rec.N-1)] ... rectangle access (members: x0,y0 is position and xs,ys is size)
好的,下面是一些binpack算法,解释:

  • 准备数据

    • 按Y大小降序对矩形进行排序(索引排序到
      ix[]
      array)
    • 查找Y尺寸相同(+/-acc)的所有矩形
    • 按X大小降序排序(索引排序到
      ix[]
      array)
    • 并记住它们在
      ix[]
      中的开始/结束索引…到
      lin[].i0,lin[].i1
    • 还可以将这些矩形的累积宽度计算为
      lin[].xs
  • 使用整行(图像的红色部分)

    搜索宽度大于换行大小的所有
    lin[]
    。如果找到,则用它填充该行,并将使用的矩形标记为已使用(同时删除已使用的宽度),然后移动到下一行

  • 尝试填充行分割(不是整个页面)(图像的绿色部分)

    计算线分割的最小非零高度,并将其用作高度填充限制,并将分割堆叠在一起,以填充整行。我使用分割
    line/2+line/4+line/8+line/16…=~line

  • 将仍然未使用的矩形换行到页面大小(图像的蓝色部分)

  • [Notes]

    这种方法远远不是最优的,代码也没有优化,但仍然足够有效。对于450个大小为线性随机的盒子
    (0.5..10.0)
    平均运行时间为
    ~2.8ms
    ,我认为这很好。您可以通过分而治之而不是我的直线划分来改进这一点。填充整条直线,然后使用剩余直线递归填充区域划分


    希望有帮助…如果有任何不清楚的地方,请评论我…

    这称为“装箱问题”,一般的解决方案是NP难的。我认为您应该先按高度将矩形分组。应用“装箱”每一组的算法都是分开的。一般问题是很难确定的。但是黑熊你能限制这个问题吗?或者它必须是一个精确的解决方案吗?如果没有,其他一些技巧可能会使你变得更紧凑…如果一些盒子不太高,你仍然可以使用蛮力攻击。因此,你唯一需要改变的是行中方框的顺序。为了加快速度,你可以忽略相同大小矩形的排列。当然,如果你有100个以上的记录,那么速度会很慢。在这种情况下,A.I.Breveleri的评论建议更好的解决方案,就像Jacob所说的,你找不到最佳解决方案高效地搜索。要找到近似好的解决方案,您有两种选择。一种是使用贪婪算法,在图片中逐个添加矩形,尝试在每一步中将封闭区域矩形增加最小值。另一种方法是使用回溯搜索。在这种情况下,您负责设计有效的启发式算法。