Related
I have the following list of tuples:
>>> import itertools
>>> import numpy as np
>>> grid = list(itertools.product((1,2,3),repeat=2))
>>> grid
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
I'd like to reshape this list in a sensible way (e.g. using numpy if possible) to be 3x3 as follows:
[[(1, 1), (1, 2), (1, 3)],
[(2, 1), (2, 2), (2, 3)],
[(3, 1), (3, 2), (3, 3)]]
When I do np.reshape(grid, (3, 3)) I get the following error: ValueError: cannot reshape array of size 18 into shape (3,3) (size 18??)
I've tried variations of np.reshape(grid, (3, 3, 2)) but these don't return the 3x3 grid given above.
This will do the job:
new_grid = np.empty(len(grid), dtype='object')
new_grid[:] = grid
new_grid = new_grid.reshape(3, 3)
This outputs:
array([[(1, 1), (1, 2), (1, 3)],
[(2, 1), (2, 2), (2, 3)],
[(3, 1), (3, 2), (3, 3)]], dtype=object)
The object type will remain tuple:
type(new_grid[0, 0])
tuple
18 comes from the fact that you have a list of 9 tuples, each containing 2 items; thus, 9 * 2 = 18. numpy automatically converts the tuples to part of the array.
You can either use LeonardoVaz's answer or do it speedily with nested list comprehension:
reshaped_grid = [[grid[i+j] for j in range(3)] for i in range(0, len(grid), 3)]
Output:
>>> reshaped_grid
[
[(1, 1), (1, 2), (1, 3)],
[(2, 1), (2, 2), (2, 3)],
[(3, 1), (3, 2), (3, 3)]
]
I'm trying to understand why it is that the combinations of -let's say- 0 and 1 are only: [(0, 0), (0, 1), (1, 1)] and why (1,0) is not included.
The same goes for all the combinations of pairs of 0,1,2,3.
I would like to get: (0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3), (3, 0), (3, 1), (3, 2), (3, 3)
But my code is only giving me: [(0, 0), (0, 1), (0, 2), (0, 3), (1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]
My/the code, which I got from realpython.com/python-itertools/ :
import itertools as com
x = list(com.combinations_with_replacement([0,1,2,3], 2))
How can I edit the code so that it prints all the desired combinations?
You would want to use itertools.product since you want the cartesian product:
>>> import itertools
>>> list(itertools.product([0, 1, 2, 3], repeat=2))
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3), (3, 0), (3, 1), (3, 2), (3, 3)]
Note you don't want to use itertools.permutations since the output will not contain entries like (0, 0), (1, 1), (2, 2), or (3, 3) since each element in the iterable is only used once.
In order to get all possible combinations, you need to use the product function:
import itertools as com
x = list(com.product([0,1,2,3], repeat=2))
print(x)
As stated in Python docs, this is the same as:
x = [(y,z) for y in [0,1,2,3] for z in [0,1,2,3]]
This will return:
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3), (3, 0), (3, 1), (3, 2), (3, 3)]
I have a list of points
lst = [1,2,3,4,5]
With itertools I get all possible combinations of lines ((1,2)=(2,1)): itertools.combinations(lst, 2)
[(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
I want to get list of lists of tuples(with unique points), like this
[
[(1,2),(3,4)],
[(1,2),(3,5)],
[(1,2),(4,5)],
[(1,3),(2,4)],
[(1,3),(2,5)],
...
[(2,3),(4,5)]
]
Ok, this is interesting xD. All you need is provided by itertools, you just have to combine it the correct way. Have a look at this:
import itertools
lst = [1,2,3,4,5]
points = list(itertools.combinations(lst, 2))
# [(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
f = lambda p: filter(lambda sub: not any(x in sub for x in p), points)
res = []
for p in points:
res.extend(list(itertools.product([p], f(p))))
# corresponding list-comprehension solution
# res = list(itertools.chain.from_iterable(itertools.product([p], f(p)) for p in points))
which returns:
res = [((1, 2), (3, 4)), ((1, 2), (3, 5)), ((1, 2), (4, 5)), ((1, 3), (2, 4)), ((1, 3), (2, 5)), ((1, 3), (4, 5)), ((1, 4), (2, 3)), ((1, 4), (2, 5)), ((1, 4), (3, 5)), ((1, 5), (2, 3)), ((1, 5), (2, 4)), ((1, 5), (3, 4)), ((2, 3), (1, 4)), ((2, 3), (1, 5)), ((2, 3), (4, 5)), ((2, 4), (1, 3)), ((2, 4), (1, 5)), ((2, 4), (3, 5)), ((2, 5), (1, 3)), ((2, 5), (1, 4)), ((2, 5), (3, 4)), ((3, 4), (1, 2)), ((3, 4), (1, 5)), ((3, 4), (2, 5)), ((3, 5), (1, 2)), ((3, 5), (1, 4)), ((3, 5), (2, 4)), ((4, 5), (1, 2)), ((4, 5), (1, 3)), ((4, 5), (2, 3))]
It basically boils down to itertools.combinations (which you already did) with itertools.product. The twist is the filtering performed between the two (see f = lambda ...). If you need further assistance understanding the code, let me know.
I want to write a function where given the two integers "n" and "p", it generates all the invertible matrices of order n where the elements come from {0,1,...,p-1}.
I have the following code :
import itertools
import numpy as np
def invertible_matrices(n, p):
invertibleMatrices = set()
# generates all the possible matrices
x = [y for y in range(p)]
a = [j for j in itertools.product(x, repeat=n)]
b = {k for k in itertools.product(a, repeat=n)}
for each in b:
if np.linalg.det(each) != 0:
invertibleMatrices.add(each)
return invertibleMatrices
for n=2 and p=2 it works fine but for n=2 and p=3 I get 50 while the answer is 48.
any help would be appreciated.
p.s: if you're familiar with group theory I'm trying to find all the elements of GL(n, p) (the general linear group over a finite field with p elements)
I guess you want the determinant modulo p (which is the determinant in the context of GL(n,p), i.e. over the finite field with p elements).
if not np.isclose((np.linalg.det(each)+1)%p,1):
invertibleMatrices.add(each)
Note: the +1 is to avoid wrap around of small numerical errors.
Use inspect_matrix() for debugging, get_invertible_matrices() for using a set comprehension to determine all invertible matrices, and get_determinant_1_matrices() to get the ones with determinant 1:
import itertools
import numpy as np
def inspect_matrix(n, p):
"""Examine a single, square matrix."""
a = list(itertools.product(list(range(p)), repeat=n))
matrices = {k
for k in itertools.product(a, repeat=n)
}
matrix = next(iter(matrices)) # Inspect one of the matrices
determinant = np.linalg.det(matrix)
print(f"{matrix = }\n{determinant = }")
print(f"inverse = {(inverse:=np.linalg.inv(matrix))}") if determinant != 0.0 else print("Matrix is not invertible")
return inverse
def get_invertible_matrices(n, p):
"""Generates all the possible matrices."""
a = list(itertools.product(list(range(p)), repeat=n))
invertible_matrices = {k
for k in itertools.product(a, repeat=n)
if not np.isclose((np.linalg.det(k) + 1) % p, 1)
}
print(f"{len(invertible_matrices) = }")
return invertible_matrices
def get_determinant_1_matrices(n, p):
"""Generates all the square matrices with determinant 1."""
a = list(itertools.product(list(range(p)), repeat=n))
if p==2:
det_1_matrices = {k
for k in itertools.product(a, repeat=n)
if np.isclose((np.linalg.det(k))%p,1)
}
else:
det_1_matrices = {k
for k in itertools.product(a, repeat=n)
if np.isclose((np.linalg.det(k)+1)%p,2)
}
print(f"{len(det_1_matrices) = }")
return det_1_matrices
def main():
print(get_invertible_matrices(n=2, p=2))
print(get_invertible_matrices(n=2, p=3))
print(get_determinant_1_matrices(n=2, p=2))
print(get_determinant_1_matrices(n=2, p=3))
if __name__ == '__main__':
main()
returns:
len(invertible_matrices) = 6
{((1, 1), (0, 1)), ((1, 0), (0, 1)), ((1, 0), (1, 1)), ((0, 1), (1, 0)), ((0, 1), (1, 1)), ((1, 1), (1, 0))}
len(invertible_matrices) = 48
{((1, 0), (0, 1)), ((1, 2), (0, 2)), ((2, 1), (1, 0)), ((0, 2), (2, 0)), ((0, 1), (2, 0)), ((1, 1), (1, 0)), ((2, 1), (1, 1)), ((2, 2), (2, 0)), ((1, 1), (2, 1)), ((1, 2), (1, 0)), ((2, 1), (2, 2)), ((2, 0), (0, 2)), ((1, 2), (1, 1)), ((2, 2), (0, 2)), ((1, 0), (0, 2)), ((1, 1), (1, 2)), ((1, 2), (2, 2)), ((2, 1), (0, 1)), ((1, 1), (0, 1)), ((0, 2), (1, 0)), ((0, 1), (1, 0)), ((2, 0), (2, 1)), ((0, 2), (2, 1)), ((2, 2), (1, 0)), ((0, 1), (2, 1)), ((1, 2), (0, 1)), ((0, 2), (1, 1)), ((2, 0), (1, 1)), ((0, 1), (1, 1)), ((2, 2), (2, 1)), ((2, 0), (2, 2)), ((0, 2), (2, 2)), ((2, 1), (2, 0)), ((0, 1), (2, 2)), ((1, 0), (2, 1)), ((1, 0), (1, 1)), ((1, 1), (2, 0)), ((2, 0), (1, 2)), ((0, 2), (1, 2)), ((0, 1), (1, 2)), ((1, 0), (2, 2)), ((2, 0), (0, 1)), ((1, 2), (2, 0)), ((2, 2), (1, 2)), ((2, 1), (0, 2)), ((1, 0), (1, 2)), ((2, 2), (0, 1)), ((1, 1), (0, 2))}
len(det_1_matrices) = 6
{((0, 1), (1, 1)), ((0, 1), (1, 0)), ((1, 0), (0, 1)), ((1, 0), (1, 1)), ((1, 1), (0, 1)), ((1, 1), (1, 0))}
len(det_1_matrices) = 24
{((2, 2), (0, 2)), ((0, 2), (1, 2)), ((1, 1), (0, 1)), ((1, 2), (2, 2)), ((2, 1), (2, 0)), ((1, 0), (0, 1)), ((2, 0), (2, 2)), ((2, 1), (1, 1)), ((1, 1), (2, 0)), ((1, 0), (2, 1)), ((1, 2), (0, 1)), ((1, 2), (1, 0)), ((2, 0), (0, 2)), ((1, 0), (1, 1)), ((1, 1), (1, 2)), ((0, 2), (1, 0)), ((0, 1), (2, 2)), ((0, 2), (1, 1)), ((0, 1), (2, 1)), ((2, 0), (1, 2)), ((0, 1), (2, 0)), ((2, 2), (2, 1)), ((2, 2), (1, 0)), ((2, 1), (0, 2))}
how should I make my check for conflict work and go through all possible ways so as to return the optimal way??
objectiv: return optimal coordinates solution without conflict for the instance e.g (0,0) , (0,2)..
what we have an example (n*m)=(5*5):
A for Vertically: height=a=3, width=b=2
B for horizontally:height=a=2, width=b=3
if A=(0,0) means: e.g (0,0) till (0+height,O+width) must fit in n*m and must not be occupied
coordinates={'C': [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)]}
so i want to test as from (0,0) if A or B passes recursively and return an optimal solution at the end, i have tried this in form of a tree it didn't work, since i always need to check on already solved solutions to know if next coordinate fits or not
dic= dict({"A": [], "B": []})
p={'C': [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)]}
def enumOptimal(p,dic,ii):
if A : dic['A'].append(A)
enumOptimal(next p,dic,ii)
if B : dic['B'].append(B)
enumOptimal(next p,dic,ii)
enum(next Point, dic)#in case neither A nor B fits
if ii >len(p): print dic