Сгенерируйте массив Numpy четных целых чисел, суммирующий значение - PullRequest
1 голос
/ 13 июля 2020

Существует ли решение numpy, которое позволило бы вам инициализировать массив на основе следующих условий?

  1. Количество элементов на оси 1. (В приведенном ниже примере у вас есть 4 места в каждый элемент массива)
  2. Сумма значений. (Сумма всех элементов равна 8)
  3. Размер шага. (Используя приращение 2)

По сути, это показывает все комбинации из 4 значений, которые вы можете добавить для достижения желаемой суммы (8) с размером шага 2.

Мои эксперименты терпит неудачу, когда я устанавливаю размер оси 1 больше 6, а сумму больше 100. Должен быть способ сделать это лучше, чем то, что я пытался.

array([[0, 0, 0, 8],
       [0, 0, 2, 6],
       [0, 0, 4, 4],
       [0, 0, 6, 2],
       [0, 0, 8, 0],
       [0, 2, 0, 6],
       [0, 2, 2, 4],
       [0, 2, 4, 2],
       [0, 2, 6, 0],
       [0, 4, 0, 4],
       [0, 4, 2, 2],
       [0, 4, 4, 0],
       [0, 6, 0, 2],
       [0, 6, 2, 0],
       [0, 8, 0, 0],
       [2, 0, 0, 6],
       [2, 0, 2, 4],
       [2, 0, 4, 2],
       [2, 0, 6, 0],
       [2, 2, 0, 4],
       [2, 2, 2, 2],
       [2, 2, 4, 0],
       [2, 4, 0, 2],
       [2, 4, 2, 0],
       [2, 6, 0, 0],
       [4, 0, 0, 4],
       [4, 0, 2, 2],
       [4, 0, 4, 0],
       [4, 2, 0, 2],
       [4, 2, 2, 0],
       [4, 4, 0, 0],
       [6, 0, 0, 2],
       [6, 0, 2, 0],
       [6, 2, 0, 0],
       [8, 0, 0, 0]], dtype=int64)

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Вот небольшой код, который позволит вам набрать oop желаемых комбинаций. Требуется 3 параметра:

  • itsize: количество элементов.
  • itsum: сумма значений.
  • itstep: размер шага.

Может потребоваться его оптимизация, если вычисления, которые вы выполняете в FOR l oop, невелики. I l oop больше комбинаций, чем необходимо (все i,j,k,l, которые принимают значения из 0,itstep,2*itstep,...,itsum), и оставляю только те, которые проверяют условие, которые в сумме дают itsum. Массив большого размера не вычисляется, и строки вычисляются на лету при итерации, поэтому у вас не будет проблем с памятью:

class Combinations:
  def __init__(self, itsize, itsum, itstep):
    assert(itsum % itstep==0) # Sum is a multiple of step
    assert(itsum >= itstep) # Sum bigger or equal than step
    assert(itsize > 0) # Number of elements >0
    self.itsize = itsize # Number of elements
    self.itsum = itsum # Sum parameter
    self.itstep = itstep # Step parameter
    self.cvalue = None # Value of the iterator
  def __iter__(self):
    self.itvalue = None
    return self
  def __next__(self):
    if self.itvalue is None: # Initialization of the iterator
      self.itvalue = [0]*(self.itsize)
    elif self.itvalue[0] == self.itsum: # We reached all combinations the iterator is restarted
      self.itvalue = None
      return None
    while True: # Find the next iterator value
      for i in range(self.itsize-1,-1,-1):
        if self.itvalue[i]<self.itsum:
          self.itvalue[i] += self.itstep
          break
        else:
          self.itvalue[i] = 0
      if sum(self.itvalue) == self.itsum:
        break
    return self.itvalue # Return iterator value

myiter = iter(Combinations(4,8,2))

for val in myiter:
  if val is None:
    break
  print(val)

Вывод:

% python3 script.py
[0, 0, 0, 8]
[0, 0, 2, 6]
[0, 0, 4, 4]
[0, 0, 6, 2]
[0, 0, 8, 0]
[0, 2, 0, 6]
[0, 2, 2, 4]
[0, 2, 4, 2]
[0, 2, 6, 0]
[0, 4, 0, 4]
[0, 4, 2, 2]
[0, 4, 4, 0]
[0, 6, 0, 2]
[0, 6, 2, 0]
[0, 8, 0, 0]
[2, 0, 0, 6]
[2, 0, 2, 4]
[2, 0, 4, 2]
[2, 0, 6, 0]
[2, 2, 0, 4]
[2, 2, 2, 2]
[2, 2, 4, 0]
[2, 4, 0, 2]
[2, 4, 2, 0]
[2, 6, 0, 0]
[4, 0, 0, 4]
[4, 0, 2, 2]
[4, 0, 4, 0]
[4, 2, 0, 2]
[4, 2, 2, 0]
[4, 4, 0, 0]
[6, 0, 0, 2]
[6, 0, 2, 0]
[6, 2, 0, 0]
[8, 0, 0, 0]
0 голосов
/ 13 июля 2020

Я попробовал это и также обнаружил, что при таком размере он значительно замедляется. Я думаю, что отчасти проблема в том, что выходной массив в этот момент становится довольно большим. Я не на 100% уверен, что мой код верен, но график показывает, как размер массива растет с условием 2 (сумма значений в каждой строке). Я не делал 100, но похоже, что это будет около 4000000 строк

график

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...