【问题标题】:Brute force to generate possible permutations蛮力产生可能的排列
【发布时间】:2020-12-12 02:54:47
【问题描述】:

我有 4 个点组,每个点组包含 5 个不同的 3D 位置。我的目标是在不重复顺序的情况下为每个组强制所有可能的四个排列并将它们打印为(5x3)array。例如。对于输入数据:

1,2,3
4,5,6
7,8,9
10,11,12
13,14,15
16,17,18
19,20,21
22,23,24
25,26,27
28,29,30
31,32,33
34,35,36
37,38,39
40,41,42
43,44,45
46,47,48
49,50,51
52,53,54
55,56, 57
58,59,60

我读了文件:

def read_file(name):
with open(name, 'r') as f:
    data = []
    for line in f:
        l = line.strip()
        cols = [float(i) for i in line.split(',')]
        data.append(cols)
    return np.array(data) 

并重塑它以使 4x(5x3) 数组被暴力破解:

def main():
    filePath= 'C:/Users/retw/input.txt'

    data = read_file(filePath)
    print('data:', data, type(data), data.shape)

    reshapedData = data.reshape(4, 5, 3)
    print('reshapedData :', reshapedData, type(reshapedData), reshapedData.shape)

当前输出如下:

respahedData: [[[ 1.  2.  3.]
                [ 4.  5.  6.]
                [ 7.  8.  9.]
                [10. 11. 12.]
                [13. 14. 15.]]

                [[16. 17. 18.]
                 [19. 20. 21.]
                 [22. 23. 24.]
                 [25. 26. 27.]
                 [28. 29. 30.]]

                [[31. 32. 33.]
                 [34. 35. 36.]
                 [37. 38. 39.]
                 [40. 41. 42.]
                 [43. 44. 45.]]

                 [[46. 47. 48.]
                  [49. 50. 51.]
                  [52. 53. 54.]
                  [55. 56. 57.]
                  [58. 59. 60.]]] <class 'numpy.ndarray'> (4, 5, 3)

在蛮力之后,排列为数组或列表应如下所示:

[[1,2,3]
 [16,17,18]
 [31,32,33]
 [46,47,48]] 

[[1,2,3]
 [19,20,21]
 [31,32,33]
 [46,47,48]]

[[1,2,3]
 [22,23,24]
 [31,32,33]
 [46,47,48]]
 etc, 
 

直到

 [[13,14,15]
 [28,29,30]
 [43,44,45]
 [58,59,60]]

编辑 对于给定的两个4x3 数组作为输入:

[[[1,2,3]
[4,5,6]]

[7,8,9]
[10,11,12]]]

暴力破解后的输出应该是:

[[1,2,3]
[7,8,9]]

[[1,2,3]
[10,11,12]]

[[4,5,6]
[7,8,9]]

[[4,5,6]
[10,11,12]]

【问题讨论】:

  • 您尝试创建的值的名称和括号符号非常令人困惑。我不知道在这种情况下什么是“组合”,你也没有以我能理解的任何方式解释它,所以我什至无法开始帮助你。如果您正在处理 numpy 数组,请显示实际数组,而不是伪代码废话。
  • 我编辑了我的问题以简化我的问题

标签: python python-3.x


【解决方案1】:

这是一个使用numpy 的解决方案和一个似乎可以工作的生成器,生成正确数量的连击 (625),并根据您的需要对它们进行排序...

import numpy as np

f_in = 'data.csv'
data = []
with open(f_in, 'r') as f:

    for line in f:
        l = line.strip()
        cols = [float(i) for i in line.split(',')]
        data.append(cols)

data = np.array(data).reshape((4,5,3))
#print(data)

def result_gen(data):
    odometer = [0, 0, 0, 0]
    roll_seq = [1, 2, 3, 0]  # the sequence of positions by which to roll the odometer
    expired = False
    while not expired:
        res = data[[0, 1, 2, 3], [odometer]]

        for i in roll_seq:
            if odometer[i] < 4:
                odometer[i] += 1
                break
            else:
                if i == 0:  # we have exhausted all combos
                    expired = True
                odometer[i] = 0 
        yield res

my_gen = result_gen(data)

a = list(my_gen)
print(len(a))
for t in a[:6]:
    print(t)

产量:

625
[[[ 1.  2.  3.]
  [16. 17. 18.]
  [31. 32. 33.]
  [46. 47. 48.]]]
[[[ 1.  2.  3.]
  [19. 20. 21.]
  [31. 32. 33.]
  [46. 47. 48.]]]
[[[ 1.  2.  3.]
  [22. 23. 24.]
  [31. 32. 33.]
  [46. 47. 48.]]]
[[[ 1.  2.  3.]
  [25. 26. 27.]
  [31. 32. 33.]
  [46. 47. 48.]]]
[[[ 1.  2.  3.]
  [28. 29. 30.]
  [31. 32. 33.]
  [46. 47. 48.]]]
[[[ 1.  2.  3.]
  [16. 17. 18.]
  [34. 35. 36.]
  [46. 47. 48.]]]
[Finished in 0.2s]

【讨论】:

  • 如何在这里使用字典而不是列表进行排列,以了解从哪个数组行生成输出?我想知道每个t 的每个行号。例如。 t(rowNumber[[1. 2. 3.], rowNumber[16. 17. 18.], rowNumber[31. 32. 33.], rowNumber[46. 47. 48.]])
  • 我在上面给了你一个工作示例。您可以在生成器中创建您想要的字典响应,而不是返回一个 numpy 数组。
  • 如果我在 for 循环 res = dict(enumerate(data[roll_seq][i])) print("Dict:", res) 中创建字典,它会为我提供当前重构数组的行号,但不会说明该索引是从哪一行创建的。对于您的解决方案中的第一个排列,数据应该看起来像 [[data0, row0[ 1. 2. 3.] data1, row0[16. 17. 18.] data2, row0[31. 32. 33.] data3, row0[46. 47. 48.]]] 因为第一个 4x3 数组是从重新整形的数组行创建的。第二次迭代:[[0, 0[ 1. 2. 3.] 1, 1[19. 20. 21.] 2, 0[31. 32. 33.] 3, 0[46. 47. 48.]]]感谢您的帮助!
  • 生成器中的行索引是odometer。因此,您需要将其合并到您的字典结构中,而不是枚举中。尝试进行字典理解,其中 key 是(数据,行),value 是行...
  • 使用此语句:res = { (d, row) : data[d, row] for (d, row) in enumerate(odometer)}
【解决方案2】:

看起来你想创建这样的东西。

import numpy as np
a = np.arange(1,61).reshape(4,5,3)
print (a)
b = np.zeros((20,4,3))

for k in range(4):
    for i in range(4):
        for j in range(5):
            if i == k:
                b[5*k + j][i] = a[i][j]
            else:
                b[5*k + j][i] = a[i][0]

print (b) 

这个输出将是:

[[[ 1.  2.  3.]
  [16. 17. 18.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[ 4.  5.  6.]
  [16. 17. 18.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[ 7.  8.  9.]
  [16. 17. 18.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[10. 11. 12.]
  [16. 17. 18.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[13. 14. 15.]
  [16. 17. 18.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [16. 17. 18.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [19. 20. 21.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [22. 23. 24.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [25. 26. 27.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [28. 29. 30.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [16. 17. 18.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [16. 17. 18.]
  [34. 35. 36.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [16. 17. 18.]
  [37. 38. 39.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [16. 17. 18.]
  [40. 41. 42.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [16. 17. 18.]
  [43. 44. 45.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [16. 17. 18.]
  [31. 32. 33.]
  [46. 47. 48.]]

 [[ 1.  2.  3.]
  [16. 17. 18.]
  [31. 32. 33.]
  [49. 50. 51.]]

 [[ 1.  2.  3.]
  [16. 17. 18.]
  [31. 32. 33.]
  [52. 53. 54.]]

 [[ 1.  2.  3.]
  [16. 17. 18.]
  [31. 32. 33.]
  [55. 56. 57.]]

 [[ 1.  2.  3.]
  [16. 17. 18.]
  [31. 32. 33.]
  [58. 59. 60.]]]

我总共可以循环 20 个 4 x 3 的数组。

【讨论】:

  • 很遗憾没有。此解决方案按组创建排列。我需要排列列明智。请查看我的预期输出。在第一次迭代中,取所有组的第一列,在第二次中,取第 1 组的第一列,第 2 组的第二列和第 3 组和第 4 组的第一列。所以它应该在下一次迭代中继续
  • 是的。我知道了。我只需要稍微调整一下代码。再开几次会后会继续努力
  • @mystic.06,更新了答案。我们有 80 行要查看(或 20 x 4 x 3 数组)
  • 排列 [[[ 1. 2. 3.] [ 4. 5. 6.] [ 7. 8. 9.] [10. 11. 12.] [13. 14. 15.]] 重复了几次。例如。 [[ 4. 5. 6.] [16. 17. 18.] [31. 32. 33.] [46. 47. 48.]] 不见了。我猜它不会对所有可能的行进行迭代。由于我们有 20 行和 4 个样本,所以 perms 的总数应该是 116280。但是我们消除了重复,因为 [1,2,3] 与 [3,2,1] 或 [2,3,1] 相同] 等等,我们应该有 116280/5! =969 种不同的排列。有了上面的答案,我们只有 60 个排列。是的,我们需要考虑 80x4x3 阵列。 ——
  • 我用 2x(4x3) 数组和预期输出的示例输入数据编辑了我的问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-06-10
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多