2

私はPythonコードに特定のケースがあります。コードを実行するたびに、RAM メモリが増加し、1.8 GB に達してクラッシュします。

import itertools
import csv
import pokersleuth

cards = ['2s',  '3s',   '4s',   '5s',   '6s',   '7s',   '8s',   '9s',   'Ts',   'Js',   'Qs',   'Ks',   'As',   '2h',   '3h',   '4h',   '5h',   '6h',   '7h',   '8h',   '9h',   'Th',   'Jh',   'Qh',   'Kh',   'Ah',   '2c',   '3c',   '4c',   '5c',   '6c',   '7c',   '8c',   '9c',   'Tc',   'Jc',   'Qc',   'Kc',   'Ac',   '2d',   '3d',   '4d',   '5d',   '6d',   '7d',   '8d',   '9d',   'Td',   'Jd',   'Qd',   'Kd',   'Ad']
flop = itertools.combinations(cards,3)

a1 = 'Ks' ; a2 = 'Qs'
b1 = 'Jc' ; b2 = 'Jd'

cards1 = a1+a2
cards2 = b1+b2

number = 0
n=0
m=0

for row1 in flop:
    if (row1[0] <> a1 and row1[0] <>a2 and row1[0] <>b1 and row1[0] <>b2) and (row1[1] <> a1 and row1[1] <>a2 and row1[1] <>b1 and row1[1] <>b2) and (row1[2] <> a1 and row1[2] <> a2 and row1[2] <> b1 and row1[2] <> b2):
        for row2 in cards:
            if (row2 <> a1 and row2 <> a2 and row2 <> b1 and row2 <> b2 and row2 <> row1[0] and row2 <> row1[1] and row2 <> row1[2]):
                s = pokersleuth.compute_equity(row1[0]+row1[1]+row1[2]+row2, (cards1, cards2))
                if s[0]>=0.5:
                    number +=1
                    del s[:]
                del s[:]

        print number/45.0
        number = 0
        n+=1
4

2 に答える 2

2

メモリ リークが発生したテストでは決定的な結果は得られませんでしたが、montecarlo.dll では発生しなかったという前提の下でmultiprocessing.Pool()、作業を小さなチャンクに分割して、以前に終了できるいくつかのプロセスにロードすることを考えました。彼らは過剰なメモリを使い始めます:

from itertools import combinations, product, islice
from multiprocessing import Pool
from pokersleuth import compute_equity

num_procs = 4
num_jobs = 256
chunk_size = num_procs * num_jobs

join = ''.join

drawn = a1, a2, b1, b2 = 'Ks', 'Qs', 'Jc', 'Jd'
pairs = (a1 + a2, b1 + b2)

deck = (join(reversed(c)) for c in product('shcd', '23456789TJQKA'))
deck = [card for card in deck if card not in drawn]

def compute_chances(cards):
    return sum(compute_equity(cards + card, pairs)[0] >= 0.5
               for card in deck if card not in cards) / 45.0

if __name__ == '__main__':
    combis = (join(each) for each in combinations(deck, 3))
    i = 0
    while True:
        pool = Pool(processes=num_procs)
        chunk = list(islice(combis, chunk_size))
        for i, chances in enumerate(pool.imap(compute_chances, chunk), i + 1):
            print i, chances
        pool.terminate()
        if len(chunk) < chunk_size:
            break

結果は、プログラムと同じです。

17 の最後の 7 つのループ (17296 の組み合わせとchunk_size1024)のメモリ消費量について、タスク マネージャーは次のように述べています。

10ループ

各ループは約 400 MB を使用し、すべての組み合わせを処理するのに 34 分かかりました。

カードのデッキ全体を手動で入力する代わりに、コンピューターにカードを作成してもらいます。私はコンピューターができることをすることを拒否します。

各プロセスに渡されるデータの量をできるだけ少なくするために、3 枚のカードの各組み合わせのみを に送信し、compute_chances()それ以外はすべてそこで計算します。

montecarlo.dll が再入可能かどうかはわかりませんが、結果は再入可能であることを示しているようです。

num_procs私のコードのとの値はnum_jobs、私のマシンでうまく機能しました。それらをいじって、自分に最適な設定を見つける必要があります。

于 2012-11-30T04:55:01.913 に答える
1

Linuxで実行していて(そうですか?)、Linux のプロセスはメモリ サイズを減らすことができないため、システムの最大プロセス イメージ サイズに達しています。ウィンドウズ。

あなたのオプションは、これを分割して、メモリ制限に達した後に再開できるようにすること、より高いプロセスサイズ制限でカーネルをコンパイルすること、または Windows で実行することです。

于 2012-11-29T21:00:31.533 に答える