【问题标题】:How to create matrix nxn with unique values and no consecutive sequence in python?如何在python中创建具有唯一值且没有连续序列的矩阵nxn?
【发布时间】:2020-11-13 09:25:50
【问题描述】:

我正在尝试创建值范围从 0 到 n^2 的 nxn 矩阵。 行列中不能有序列,n

以下是执行输出的示例:

array([[ 8, 13, 39,  1, 22, 37,  2],
       [ 6, 26, 36,  3, 29, 35, 16],
       [18, 20, 46, 28, 15, 12, 43],
       [ 7, 24, 14, 41, 32, 21, 27],
       [34, 31,  9, 44, 30, 48, 45],
       [11, 33, 40, 10, 38,  0,  5],
       [17, 23,  4, 19, 25, 47, 42]])

【问题讨论】:

  • @Timus 抱歉,我是这里和 python 的新手,我已经更新了我的帖子。感谢您的评论,请告诉我我还应该做什么

标签: python arrays matrix


【解决方案1】:

创建您的值,随机选择而不替换(或使用随机播放)并重塑数组。

import numpy as np

# dimension
n = 5
values = np.arange(0, n**2)

# randomly selected (or use shuffle)
selected = np.random.choice(values, size = n * n, replace = False)

# reshape array to matrix
matrix = np.reshape(selected, (n, n))

array([[21,  5, 12, 23,  4],
       [13, 10, 19, 22, 20],
       [ 7,  2, 15, 18, 17],
       [ 0, 16,  6,  8, 24],
       [11,  1,  9, 14,  3]])

【讨论】:

    【解决方案2】:

    这是一个可能的解决方案:

    import random
    import pprint
    
    number_rows_columns = 5
    number_list = [i for i in range(number_rows_columns**2)]
    
    final_matrix = []
    for row in range(number_rows_columns):
        new_column = []
        for column in range(number_rows_columns):
            new_column.append(random.choice(number_list))
            number_list.remove(new_column[-1])
        final_matrix.append(new_column)
    pprint.pprint(final_matrix)
    

    此代码的示例输出:

    [[6, 13, 10, 20, 24],
     [2, 14, 16, 21, 19],
     [0, 8, 17, 15, 5],
     [3, 18, 7, 12, 23],
     [22, 1, 4, 9, 11]]
    

    更新:要消除“排序”问题,这是一个可能的解决方案:

    import random
    import pprint
    
    number_rows_columns = 20
    matrix_is_valid = False
    
    def fill_matrix():
        number_list = [i for i in range(number_rows_columns**2)]
        matrix = []
        for row in range(number_rows_columns):
            new_column = []
            for column in range(number_rows_columns):
                new_column.append(random.choice(number_list))
                number_list.remove(new_column[-1])
            matrix.append(new_column)
        return matrix
    
    def check_rows(matrix):
        global matrix_is_valid
        for row in matrix:
            for index, element in enumerate(row[:-1]):
                if abs(element - row[index + 1]) == 1:
                    matrix_is_valid = False
                    return
    
    def check_matrix(matrix):
        global matrix_is_valid
        matrix_is_valid = True
        check_rows(matrix)
        if not matrix_is_valid:
            return
        matrix = list(list(a) for a in zip(*matrix))
        check_rows(matrix)
    
    
    while not matrix_is_valid:
        final_matrix = fill_matrix()
        check_matrix(final_matrix)
    
    pprint.pprint(final_matrix)
    

    重要提示:我想说明这不是一个有效的解决方案。基本上这个算法创建一个矩阵,检查每一行和每一列(通过转置)没有数字“排序”,如果有的话,创建一个新矩阵并检查直到他得到一个有效的矩阵。 这是一个平均时间复杂度为O((n+1)!)的算法,见Bogosort加深。


    更新改进版本:这个改进版本检查每个数字插入的有效性,因此,只有当最后一个数字无法输入时,必须从头开始重建矩阵

    代码:

    import random
    import pprint
    
    number_rows_columns = 12
    matrix_is_valid = False
    counter = 0
    
    def fill_matrix():
        global matrix_is_valid
        matrix_is_valid = True
        number_list = [i for i in range(number_rows_columns**2)]
        matrix = []
        for row in range(number_rows_columns):
            new_column = []
            for column in range(number_rows_columns):
                new_column.append(random.choice(number_list))
                if (column > 0 or row > 0) and len(number_list) > 1:
                    invalid_value = True
                    if column != 0 and row != 0:
                        while abs(new_column[-1] - new_column[-2]) == 1 or abs(new_column[-1] - matrix[-1][column]) == 1:
                            new_column[-1] = random.choice(number_list)
                    elif column != 0 and row == 0:
                        while abs(new_column[-1] - new_column[-2]) == 1:
                            new_column[-1] = random.choice(number_list)
                    elif column == 0 and row != 0:
                        while abs(new_column[-1] - matrix[-1][column]) == 1:
                            new_column[-1] = random.choice(number_list)
                number_list.remove(new_column[-1])
            matrix.append(new_column)
        if abs(matrix[-1][-1] - matrix[-1][-2]) == 1 or abs(matrix[-1][-1] - matrix[-2][-1]) == 1:
            matrix_is_valid = False
        return matrix
    
    
    while not matrix_is_valid:
        final_matrix = fill_matrix()
    
    pprint.pprint(final_matrix)
    

    【讨论】:

    • 感谢您的帮助。但在某些情况下,排序仍在进行中。看来我应该考虑必须将什么值附加到 new_column
    • @Dreyar 对不起,您所说的“测序正在发生”是什么意思?你有这个代码的问题吗?通过将任何值分配给number_rows_columns,它对我来说可以正常工作
    • 抱歉我的不清楚。我的意思是在某些情况下,单行/列中有 2 个数字(可能更多)的序列(即:[12, 11, ....])。但现在我正在考虑一种可能的解决方案,如果有的话,用 for 循环检查每一行和每一列,我会用 while 循环重新排列这些行/列。
    • @Dreyar 我明白了,很抱歉我没有想到这个问题,我会考虑一下,解决后我会警告你
    • @Dreyar 我已经用可能的解决方案更新了答案!
    猜你喜欢
    • 2022-12-12
    • 2020-02-24
    • 2021-10-05
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多