簡體   English   中英

獲取python中排列的總數

[英]Get the total number of permutations in python

好的,我編寫了一個函數/方法,在確定條件是否大多數失敗之后,我可以進行一些操作,但是只有1-2次是正確的。

這是我的代碼:

def solve_current_level(self):
    self.remaining_possibilities = list(self.remaining_possibilities)
    if len(self.remaining_possibilities) > 10 ** 6:
        #self.reduce_weapon_options()
        pass

    guess = list(random.choice(self.remaining_possibilities))
    response = self.client.solve_level(self.current_level.levelNum, guess)

    if 'roundsLeft' in response:
        self.reset_remaining_possibilities()
        return None
    elif 'response' not in response:
        return response

    self.remaining_possibilities=[possibility for possibility in self.remaining_possibilities if game.Game_evaluate(guess, list(possibility)) == response['response']]
    return None

現在,當生成非常大的排列然后將其轉換為列表以檢查長度是否超過10 ** 6時,就會發生問題,然后執行其他操作並返回。 這是我當前的解決方案,但問題是,當腳本變得非常龐大時,該腳本被殺死。 我從ruby轉換了這段代碼,在ruby中可以得到枚舉器的大小而無需轉換為list,並且這個問題永遠不會發生。

這是ruby中的代碼:

def solve_current_level
  reduce_weapon_options if @remaining_possibilities.size > 10 ** 6
  if !@remaining_possibilities.kind_of?(Array)
    @remaining_possibilities = @remaining_possibilities.to_a
  end

  guess = @remaining_possibilities.sample
  response = @client.solve_level(@current_level.levelNum, guess)

  if response['roundsLeft']
    reset_remaining_possibilities
    return Nil
  elsif !response['response']
    return response
  end

  @remaining_possibilities.select! do |possibility|
    Game.evaluate(guess, possibility) == response['response']
  end
  return Nil
end

現在,您可以在ruby代碼中看到排列的長度,然后將其計算為數組/哈希值以繼續處理,如果該數目大於10 ** 6,則它將調用另一個方法“ reduce_weapon_options”。 雖然在python中沒有辦法獲得生成器的長度而不轉換成列表,但我需要它以這種方式工作,因為這時我獲得了更大的更大范圍,它被卡住並被我的服務器殺死。 我無法擴展ram,因為我需要像ruby一樣少使用ram,我絕對希望避免

self.remaining_possibilities =列表(self.remaining_possibilities)

如果條件通過/失敗,則在python中執行此操作。

注意:我正在使用itertools.permutations來計算后來保存在“ self.remaining_possibilities”中的排列

這是python和ruby中的代碼:

return (0...@numWeapons).to_a.permutation(@numGladiators)
(THIS RETURNS AN ENUMERATOR OBJECT)

return it.permutations(range(0, self.numWeapons), self.numGladiators)
(THIS RETURNS A GENERATOR OBJECT)

解決此問題的最簡單方法可能是使用排列公式來計算生成的排列數量,可以將其定義為:

from math import factorial
def nPr(n, r):
    return int(factorial(n)/factorial(n-r))

但是,這要求此數據可用,或者從創建原始排列生成器的位置開始傳遞長度。 如果不是這種情況,出於某種原因,可以使用itertools.tee()從第一個生成器生成第二個生成器,並將其僅用於計數:

def solve_current_level(self):
    self.remaining_possibilities, perm_count = itertools.tee(self.remaining_possibilities)
    # exhausting the 'teed' generator, leaving the 'original' intact:
    num_perm = sum(1 for _ in perm_count)
    if num_perm > 10 ** 6:
        #self.reduce_weapon_options()
        pass
    # here we can still use self.remaining_possibilities
    .
    .
    .

我想,既然您已經在使用itertools這並不是一個很繁重的解決方案,但仍然需要您仔細閱讀整個列表。 但是,內存占用空間要小得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM