查找数组

时间:2015-11-03 10:13:19

标签: python arrays algorithm

所以,我正在生成一个空格数组,它们具有红色或黑色的属性。但是,我想防止红色被黑色包围。我有一些例子来说明我的意思:

0 0 0 0 0 0 0 1
0 1 0 0 0 0 1 0
1 0 1 0 0 0 0 1
0 1 0 0 1 1 1 0
0 0 0 0 1 0 1 0
1 1 1 0 1 1 1 0
0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0

如果红色为0且黑色为1,那么这些都是有效的外壳,我想在生成数组时避免使用它们。我有的输入是数组的大小和我可以生成的1的数量。

我将如何做到这一点?

4 个答案:

答案 0 :(得分:2)

所以你可以做到以下几点:

  1. 用零填充数组
  2. 随机选择一个点
  3. 如果条件成立,则翻转颜色
  4. 从步骤2开始重复或退出
  5. 条件适用于全零数组。它适用于任何迭代。因此,通过归纳,最终阵列也是如此。

    在步骤4中,您可以决定是停止还是继续执行,比如说N = a * b * 1000次迭代或红色/黑色比率是否接近1.在这两种情况下,结果都会略有偏差你从全零开始。

    现在,什么是条件。您必须确保连接所有黑点并连接所有红点。换句话说,最多有2个连接的集群。翻转颜色可以创建更多连接的群集,因此只有在其数量为一或两个时才会翻转。您可以使用Union-Find算法described here非常有效地进行检查。

    编辑:如果您想要允许黑点被红色点包围但反之亦然,您可以将条件更改为具有任意数量的黑色簇,但只有0或1个红色簇。

答案 1 :(得分:2)

此代码是否适合您?
基本上我从左到右,从上到下填充矩阵 当我必须为一个单元格分配0或1时,我检查(北和西)是否添加1可以包含0;在这种情况下,我把0,否则随机0或1。

web.config

示例运行:import sys, random n = int(sys.argv[1]) m = int(sys.argv[2]) # fill matrix with zeroes matrix = [[0 for _ in xrange(m)] for _ in xrange(n)] # functions to get north, south, west and east # cell wrt this cell. # If we are going out of bounds, we suppose the matrix # is sorrounded by 1s. def get_n(r, c): if r <= 0: return 1 return matrix[r - 1][c] def get_s(r, c): if r >= n - 1: return 1 return matrix[r + 1][c] def get_w(r, c): if c <= 0: return 1 return matrix[r][c - 1] def get_e(r, c): if c >= m - 1: return 1 return matrix[r][c + 1] # Checks if the cell is already enclosed by 3 1s. def enclosed(r, c): enclosing = get_n(r, c) + get_s(r, c) + get_w(r, c) + get_e(r, c) if (enclosing > 3): raise Exception('Got a 0 enclosed by 1s') return enclosing == 3 for r in xrange(n): for c in xrange(m): # check west and north if enclosed(r, c - 1) or enclosed(r - 1, c): matrix[r][c] = 0 else: matrix[r][c] = random.randint(0, 1) print str(matrix[r][c]) + ' ', print ''

答案 2 :(得分:1)

这可能是检查条件的可能方法:

def: findStart(myArr):
    for i in range(len(myArr)):
        for j in range(len(myArr[0])):
            if(myArr[i][j] == 0):
                return (i,j)

def: checkCon(myArr, number_Ones):
    width = len(myArr[0])
    height = len(myArr)
    pen = []                      #A list of all points that are waiting to get a visit
    vis = []                      #A list of all points that are already visited
    x = findStart(myArr)

    while(len(pen) != 0):         #Visit points as long as there are points left
        p = pen.pop()             #Pick a point to visit

        if p in vis:
           #do nothing since this point already was visited

        else:
            vis.append(p)
            x,y = p

            #A vertical check
            if(x == 0 and myArr[x+1][y] == 0):
                pen.append((x+1,y))
            elif(x == (height-1) and myArr[x-1][y] == 0):
                pen.append((x-1,y))

            else:
                if(myArr[x-1][y] == 0 and x-1 >= 0):
                    pen.append((x-1,y))
                if(myArr[x+1][y] == 0):
                    pen.append((x+1,y))


            #A horizontal check    
            if(y == 0 and myArr[x][y+1] == 0):
                pen.append((x,y+1))
            elif(y == (width-1) and myArr[x][y-1] == 0):
                pen.append((x,y-1))

            else:
                if(myArr[x][y+1] == 0):
                    pen.append((x,y+1))
                if(myArr[x][y-1] == 0 and y-1 >= 0):
                    pen.append((x,y-1))                 


    print((height*width-number_Ones) == len(vis))       #if true, alle Zeros are connected and not enclosed

澄清这只是一个检查条件的概念。想法是访问所有连接的零并查看是否有任何左(未连接)。如果是这种情况,可以附上一些 当1在矩阵周围形成一个框架时,这种方法也不起作用:

1 1 1 1
1 0 0 1
1 0 0 1 
1 1 1 1

再一次,只是一个概念:)

答案 3 :(得分:0)

问题实际上有两个部分。生成板状态,然后检查它是否正确。我意识到检查正确性实际上比仅确保始终生成正确的状态更糟糕。这就是我所做的:

请注意,我已将self.WallSpaces定义为一个长度与数组高度相等的数组,由整数组成,其位数等于数组的宽度。 self.Widthself.Height提供数组的结束索引。基本上,Intersects通过检查点周围的所有空间1s来工作,除了空间的方向&#34;从&#34; (见下文)并返回True如果其中任何一个是数组的边缘或1。

def Intersects(self, point, direction):
    if (point[0] > 0):
        if (direction != [1, 0] and self.WallSpaces[point[0] - 1] & (1 << point[1]) != 0):
            return True
        if (point[1] == 0 or self.WallSpaces[point[0] - 1] & (1 << (point[1] - 1)) != 0):
            return True
        if (point[1] == self.Width or self.WallSpaces[point[0] - 1] & (1 << (point[1] + 1)) != 0):
            return True
    else:
        return True
    if (point[0] < self.Height):
        if (direction != [-1, 0] and self.WallSpaces[point[0] + 1] & (1 << point[1]) != 0):
            return True
        if (point[1] == 0 or self.WallSpaces[point[0] + 1] & (1 << (point[1] - 1)) != 0):
            return True
        if (point[1] == self.Width or self.WallSpaces[point[0] + 1] & (1 << (point[1] + 1)) != 0):
            return True
    else:
        return True
    if (point[1] == 0 or (direction != [0, 1] and self.WallSpaces[ point[0] ] & (1 << (point[1] - 1)) != 0)):
        return True
    if (point[1] == self.Width or (direction != [0, -1] and self.WallSpaces[ point[0] ] & (1 << (point[1] + 1)) != 0)):
        return True
    return False

路线GPacW.LeftGPacW.RightGPackW.UpGPacW.Down代表了移动的主要方向。这个功能通过构建&#34;墙壁来实现。在随机点的数组中,可以随机转向,当它们相交两次时结束。

def BuildWalls(self):
    numWalls = 0
    directions = [ [GPacW.Left, GPacW.Right], [GPacW.Up, GPacW.Down] ]
    start = [ random.randint(0, self.Height), random.randint(0, self.Width) ]
    length = 0
    horizontalOrVertical = random.randint(0, 1)
    direction = random.randint(0, 1)
    d = directions[horizontalOrVertical][direction]
    intersected = False
    while (numWalls < self.Walls):
        while (start == [0, 0] or start == [self.Height, self.Width] or self.Intersects(start, d)):
            start = [ random.randint(0, self.Height), random.randint(0, self.Width) ]
        if (length == 0):
            horizontalOrVertical = not horizontalOrVertical
            direction = random.randint(0, 1)
            length = random.randint(3, min(self.Height, self.Width))
            d = directions[horizontalOrVertical][direction]
        if (self.WallSpaces[ start[0] ] & (1 << start[1] ) == 0):
            self.WallSpaces[ start[0] ] |= 1 << start[1]
            numWalls += 1
            length -= 1
        if (0 <= (start[0] + d[0]) <= self.Height and 0 <= (start[1] + d[1]) <= self.Width):
            start[0] += d[0]
            start[1] += d[1]
        else:
            start = [0,0]
        if (self.Intersects(start, d)):
            if (intersected):
                intersected = False
                start = [0,0]
                length = 0
            else:
                intersected = True
    return