mystic.06
mystic.06

Reputation: 299

Brute force to generate possible permutations

I have 4 point groups, each of them contain 5 different 3D positions. My goal is to brut force all possible four permutations for each group without repeating the order and print them out as (5x3)array. E.g. for input data:

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

I read the file:

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) 

and reshape it to have 4x(5x3) arrays to be brute-forced:

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)

The current output looks like:

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)

after brut force, the permutations as array or list should look like:

[[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, 
 

until

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

Edit For given two 4x3 arrays as input:

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

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

The output after brute force should be:

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

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

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

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

Upvotes: 0

Views: 394

Answers (2)

AirSquid
AirSquid

Reputation: 11948

Here is a solution using numpy and a generator that appears to work, generates the correct number of combos (625), and sequences them as you are looking for...

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)

Yields:

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]

Upvotes: 1

Joe Ferndz
Joe Ferndz

Reputation: 8508

Looks like you want to create something like this.

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) 

The output of this will be:

[[[ 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.]]]

There are a total of 20 arrays of 4 x 3 I could get looping through this.

Upvotes: 0

Related Questions