DataFrame迷宫游戏解决方案?

时间:2017-05-21 18:20:07

标签: python pandas dataframe

所以我想通过创建一个迷宫游戏来测试我的pands技能,基本上创建一个0和1的数据帧,其中0代表一个空方块,1代表一个墙:

df = pd.DataFrame(np.random.randint(0, 2, (10,11)))

       0   1   2   3   4   5   6   7   8   9   10
   0   0   1   0   0   0   1   0   0   0   1   0
   1   1   1   1   1   0   1   1   0   0   1   1
   2   1   0   1   1   0   0   0   0   1   0   1
   3   0   0   1   0   0   0   0   1   1   0   0
   4   1   1   1   0   1   0   1   0   0   1   0
   5   0   1   0   0   1   1   1   1   1   0   1
   6   1   0   1   1   0   1   0   0   1   0   1
   7   1   1   1   1   1   0   1   1   1   1   0
   8   1   1   1   0   0   0   1   0   1   1   0
   9   0   0   1   1   1   0   1   1   0   0   0

我的想法是检查是否可以从0列到第10列只是水平或垂直地经过0。我的解决方案是(如果最后一列中有两个可以解决):

def expand(col):
    if col[0]==0: last0= 0
    else: last0= 'x'
    for ind in range(1, len(col)):
        if col[ind]==0 and (last0=='x'): last0 = ind
        if col[ind]==1: last0 = 'x'
        if col[ind]==2 and last0!='x':
            for val in range(last0, ind):
                col[val]=2
        if col[ind-1]==2 and col[ind]==0: col[ind]=2
    return col


def sol(df):
    df[0] = df.apply(lambda x: 2 if x[0]==0 else x[0], axis=1)
    for col in range(1, len(df.T)):
        df[col] = df.apply(lambda x: 2 if x[col-1]==2 and x[col]==0 else x[col], axis=1)
        df[col] = expand(df[col])
sol(df)

老实说,直到我意识到它不是一个完整的解决方案,我才为它的效率感到自豪。它只填充右侧的2s,所以如果迷宫需要向右走,那么再向上,向左和向右。这段代码无法解决。显然,我只需要像列那样多次迭代代码,因此它会左右移动,但对于巨大的迷宫来说,这将非常缓慢。

您认为什么是解决此问题的好方法?

1 个答案:

答案 0 :(得分:1)

我会递归地做:

  • where_next获取数组和位置。如果它在最后一列中,则返回True。否则,它会将当前位置设置为1,并查找0的所有相邻位置并在该位置进行递归。
  • 我通过在第一列中的所有0位置上运行来初始化。
def where_next(a, i, j):
    a = a.copy()
    n, m = a.shape
    if j == 10:
        return True
    else:
        results = []
        a[i, j] = 1
        moves = [(i, j + 1), (i, j - 1), (i - 1, j), (i + 1, j)]
        for i_, j_ in moves:
            if (0 <= i_ < n) and (0 <= j < m):
                if a[i_, j_] == 0:
                    results.append(where_next(a, i_, j_))
        return any(results)

df = pd.DataFrame(np.random.randint(0, 2, (10, 11)))
a = df.values
any([where_next(a, i, 0) for i in np.where(a[:, 0] == 0)[0]])

True
print(df)

   0   1   2   3   4   5   6   7   8   9   10
0   1   1   1   1   0   0   0   0   1   1   1
1   0   1   0   1   1   1   1   0   0   0   1
2   0   0   0   0   1   0   0   0   0   0   0
3   0   1   0   0   0   1   1   1   0   1   1
4   0   0   1   0   1   0   0   0   0   0   1
5   1   0   1   0   0   1   1   0   0   0   1
6   0   0   0   1   1   1   1   0   0   1   0
7   0   0   0   0   0   0   0   0   1   0   0
8   0   1   1   1   1   1   0   0   1   0   1
9   0   0   0   0   0   0   1   1   1   1   0