证明特定矩阵存在

时间:2017-07-08 07:57:01

标签: algorithm

我在编程论坛Ohjelmointiputka中发现了这个问题:

有人说计算机找到了解决方案,但我无法找到证据。

证明存在一个包含117个元素的矩阵,其中包含数字,以便人们可以读取数字1,2,...,100的正方形。

这里的读取意味着您固定起始位置和方向(8种可能性),然后沿着那个方向前进,连接数字。例如,如果您可以连续找到例如数字1,0,0,0,0,4,则您已找到整数100004,其中包含1,2,10,100和20的平方数,因为您可以从该序列读出1,4,100,10000和400(反向)。

但是有很多数字可以找到(准确地说是100个正方形数字,如果你删除那些包含在另一个正方形数字中的总共312位数字的数字,则为81)并且矩阵中的整数很少,你必须把所有这些方形数字都密集起来,找到这样一个矩阵是困难的,至少对我而言。

我发现如果存在这样的矩阵mxn,我们可以假设m< = n而不失一般性。因此,矩阵必须是1x1173x399x13类型。但是什么样的算法会找到矩阵?

我设法做了一个程序,检查是否可以在板上放置要添加的数字。但是我如何实现搜索算法?

# -*- coding: utf-8 -*-

# Returns -1 if can not put and value how good a solution is if can be put. Bigger value of x is better.
def can_put_on_grid(grid, number, start_x, start_y, direction):
#   Check that the new number lies inside the grid.
    x = 0
    if start_x < 0 or start_x > len(grid[0]) - 1 or start_y < 0 or start_y > len(grid) - 1:
        return -1
    end = end_coordinates(number, start_x, start_y, direction)
    if end[0] < 0 or end[0] > len(grid[0]) - 1 or end[1] < 0 or end[1] > len(grid) - 1:
        return -1
#   Test if new number does not intersect any previous number.
    A = [-1,-1,-1,0,0,1,1,1]
    B = [-1,0,1,-1,1,-1,0,1]
    for i in range(0,len(number)):
        if grid[start_x + A[direction] * i][start_y + B[direction] * i] not in ("X", number[i]):
            return -1
        else:
            if grid[start_x + A[direction] * i][start_y + B[direction] * i] == number[i]:
                x += 1
    return x

def end_coordinates(number, start_x, start_y, direction):
    end_x = None
    end_y = None
    l = len(number)
    if direction in (1, 4, 7):
        end_x = start_x - l + 1
    if direction in (3, 6, 5):
        end_x = start_x + l - 1
    if direction in (2, 0):
        end_x = start_x
    if direction in (1, 2, 3):
        end_y = start_y - l + 1
    if direction in (7, 0, 5):
        end_y = start_y + l - 1
    if direction in (4, 6):
        end_y = start_y
    return (end_x, end_y)

if __name__ == "__main__":
    A = [['X' for x in range(13)] for y in range(9)]
    numbers = [str(i*i) for i in range(1, 101)]
    directions = [0, 1, 2, 3, 4, 5, 6, 7]
    for i in directions:
        C = can_put_on_grid(A, "10000", 3, 5, i)
        if C > -1:
            print("One can put the number to the grid!")
    exit(0)

我还发现蛮力搜索或最佳首次搜索太慢了。我认为可能存在使用模拟退火,遗传算法或bin打包算法的解决方案。我也想知道是否可以以某种方式应用马尔可夫链来找到网格。不幸的是,这些对我来说似乎太难以现有技能实施。

1 个答案:

答案 0 :(得分:0)

https://github.com/minkkilaukku/square-packing/blob/master/sqPackMB.py中有一个用于该程序的程序。只需从第20行和第21行更改M = 9,N = 13。