Home > OS >  How to relocate an element in a matrix to a random empty location in another row?
How to relocate an element in a matrix to a random empty location in another row?

Time:05-03

Let's say I have a 5*5 matrix.

[[1. 2. 3. 4. 5.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0]]

For example:

I want to get '4' but '5' is in front of it. I need to relocate '5' which is unnecessary here and place it in any random available location other than the row it was in earlier.

so the matrix should look like this after the relocation

[[0. 1. 2. 3. 4.]
 [0. 0. 0. 0. 0.]
 [0. 5. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]

and if I need '3' it should relocate '4' and '5' to random locations.

please help me with this. Thanks

CodePudding user response:

In this answer, I assume that the matrix is implemented as a list of lists such as

a = [[1., 2., 3., 4., 5.],
     [0., 0., 0., 0., 0.],
     [0., 0., 0., 0., 0.],
     [0., 0., 0., 0., 0.],
     [0., 0., 0., 0., 0.]]

The function below

  • accepts two arguments, a, a 2-dimensional matrix implemented as a list of lists, and n, the number in a[0] (i.e. the first row of a) you want to shift right to the end of a[0].

  • idx is assigned the index in a[0] where n occurs.

  • The elements in the list to_relocate are all the elements in a[0] to the right of n.

  • a[0] = [0.] * (len(a[0]) - (idx 1)) a[0][:idx 1] shifts elements of a[0] right, filling the left with zeros.

  • We then randomly place the items in to_relocate to an element in any row of a other than row 0.

  • While doing so, in the set do_not_remove, we record the indices of a corresponding to elements that are replaced by elements in to_relocate so that we do not attempt to place more than one element in to_relocate at the same location in a.

from random import randrange
def change_random(n, a):
     # get index of n in a[0].
     idx = a[0].index(n)
     # values to relocate.
     to_relocate = a[0][idx   1:]
     # shift a[0] right (filling left with zeros)
     a[0] = [0.] * (len(a[0]) - (idx   1))   a[0][:idx   1]

     # records indices corresponding to elements of a 
     # that have already been replaced by elements in to_relocate.
     do_not_remove = set()
     for num in to_relocate:
          while True:
               # draw indices at random from set of valid indices (not row 0)
               ij = (randrange(1, len(a)), randrange(0, len(a[0])))
               # if element corresponding to ij has not been previously replaced, break
               if ij not in do_not_remove:
                    break
          do_not_remove.add(ij)
          a[ij[0]][ij[1]] = num

change_random(3, a)
print(a)

Sample Session:

[[0.0, 0.0, 1.0, 2.0, 3.0],
 [4.0, 0.0, 0.0, 0.0, 0.0],
 [0.0, 0.0, 0.0, 0.0, 0.0],
 [0.0, 0.0, 0.0, 0.0, 0.0],
 [5.0, 0.0, 0.0, 0.0, 0.0]]
  • Related