我目前正致力于优化我现在已有几年历史的项目。目的是在击中某个键组合后绘制图像。我几年前制作的原始版本手动移动到每个方形区域,但我最近对其进行了优化,以绘制连续方块的矩形,这使得它更快。
我想采取的下一步是优化程序绘制给定布局的方式,但我不知道从哪里开始寻找。我希望有人可以指出我正确的方向,因为我甚至无法想到一个搜索术语。
目前该程序有一个名为Draw
的函数,它接受如下输入:
Invader =
(
00100000100
00010001000
00111111100
01101110110
11111111111
10111111101
10100000101
00011011000
)
Draw(Invader, 10) ; Where 10 is the size in pixels of each square
上面的布局适用于此图片:
Draw将采用该布局,并按以下方式从上到下,从左到右绘制:
总共需要18个单独的部分来完成图片。我正在寻找的是一些可以最小化这个数字的算法。例如,以下是仅有16个部分的少数方法之一:
同样地,当前的方式和我刚刚为这张图片制作的东西之间的差异是19(65与46相比)。
我应该从哪里开始?
另外作为参考,这是当前的Draw函数:
Draw(Layout, BlockSize)
{
Len := StrLen(Layout) ; Total amount of characters
RowSize := StrLen(StrSplit(Layout, "`n")[1]) ; Size of a single row
Index := 0
While (Index < Len)
{
Length := 1
Char := GetChar(Layout, Index) ; Get next character in string
if (Char == "1")
{
; Get the number of consecutive 1s
While (GetChar(Layout, Index + Length) == "1")
{
Length := Length + 1
}
; Draw the rectangle
FillRectangle(Length, BlockSize)
}
else if (Char == "0")
{
; Get the number of consecutive 0s
While (GetChar(Layout, Index + Length) == "0")
{
Length := Length + 1
}
; Skip the entire length
MouseMove, BlockSize * Length, 0, 0, R
}
else
{
; End of line, reset position
MouseMove, -(RowSize * BlockSize), BlockSize, 0, R
}
Index := Index + Length
}
}
FillRectangle(Width, BlockSize)
{
MouseGetPos, mX, mY
mY2 := mY ; Same Y for straight line
mX2 := mX + Width * BlockSize ; Add Width of rectangle times the block size to get final X position
Loop %BlockSize%
{
; Draw line
MouseClickDrag, L, mX, mY, mX2, mY2
; Move to next line
mY -= 1
mY2 -= 1
}
; Move mouse to next position
MouseMove, 0, BlockSize - 1, 0, R
}
GetChar(String, Index)
{
return SubStr(String, Index, 1)
}
答案 0 :(得分:1)
你应该先进行某种分析。之后我建议双向传递“图像”并保留较长的行(将较长行的每个单元格标记为已通过或“黑色”,这样您就不会重复检查)。
void analyze(){
var horSize = 0, verSize = 0;
// run horizontally & vertically for each white cell
while(!reached_boundary){
++horSize ;
}
while(!reached_boundary){
++verSize ;
}
someContainer.Add( (horSize > verSize) ? horSize:verSize);
}
答案 1 :(得分:1)
这是从EpiGen的答案中扩展而来的,但我觉得需要自己的帖子来解释这些差异。
这是我现有的状态,但在所有情况下仍然不是100%最优(如下所示)。如果有任何改进,请随意添加。
因此,算法的基本流程如下:
然而,它并没有给出它看到的长度。相反,它选择的最大长度不会与具有更长长度的线相交。以下是步骤:
以下是此逻辑的实例示例。灰线表示已绘制的线条,绿线表示正在检查的线条,红线表示边界。
由于红线的水平长度大于此时的当前垂直长度,因此值以当前形式保存(垂直1,水平7)。在垂直线检查完成并找到长度为2之后,它会看到它越过了一条长度为7的线。由于将该线分割为较小的线的效率较低,因此它将其长度改为1。这就是它越过那条线之前所拥有的。这使得最终输出看起来像这样,共有16个段,据我所知这是最佳的。
但是,它在某些条件下会失败;特别是这张图片的左下角。
绿线的长度为10,它停在的行的长度为9.由于该行不大于或等于其大小,它会将离开单个块的行拆分为侧。如果这个问题得到解决,那么就我所知,这个图像将是最佳的。 (最低的我得到的是44,当前的逻辑得到45)。
无论如何,这似乎和我需要的一样好。如果在第二天左右有更好的解决方案有任何其他答案,我会看看它们。
作为一个额外的,这里有一个大型的GIF运行: