0

私はこれを持っています。

import operator
cuts = { "Emerald" : (10,125),
         "Oval" : (20,150),
         "Pear" : (35, 175),
         "Plumbbob" : (50,200),
         "Marquis" : (75, 230),
         "Crystal Ball" : (100, 260),
         "Brilliant" : (250, 350),
         "Star Cut" : (400,400),
         "Heart-shaped" : (1000, 500)
         }

def best(amount):
    "Returns most profitable cut's name."
    max_name = ""
    max_value = -10000
    for k,v in cuts.iteritems():
        value = ((float(amount) * (v[1] - 100) / 100)) - v[0]
        if value > max_value:
            max_value = value
            max_name = k
    return max_name

def create_table():
    """Creates a table like

       0-40 emerald
       40-45 Oval
       ...
       2000 + Heart-shaped
    """

しかし、私は書くことに行き詰まっていcreate_tableます。このコードは、私がプレイしているゲームを支援するためのものです。bestfunciton は、金額を指定すると、その金額で最も収益性の高いカット名を返します。範囲を示す表を作成したいと考えています。たとえば、量が 0 ~ 40 の場合、ベスト カットはエメラルド、40 ~ 45 の場合、ベスト カットはオーバルなどです。

4

2 に答える 2

1

分析ソリューションは間違いなくやり過ぎです...しかしねえ、私はやり過ぎが好きです。

まず、cutsy = mx+b形式に変換しました。

cuts = [(k, (v1-100)*0.01,-v0) for k,(v0,v1) in cuts.items()]
cuts.sort()

その結果

cuts = [
    ('Brilliant',       2.5,    -250),
    ('Crystal Ball',    1.6,    -100),
    ('Emerald',         0.25,    -10),
    ('Heart-shaped',    4.0,   -1000),
    ('Marquis',         1.3,     -75),
    ('Oval',            0.5,     -20),
    ('Pear',            0.75,    -35),
    ('Plumbbob',        1.0,     -50),
    ('Star Cut',        3.0,    -400)
]

カットのペアごとに、交点を見つけることができます-どちらかのカットの値が同じになる宝石のサイズ

from itertools import combinations

xints = []
for (na,ma,ba),(nb,mb,bb) in combinations(cuts, 2):
    xint = (bb-ba)/(ma-mb)
    val = ma*xint + ba

    # figure out which cut dominates to the right
    va = ma*(xint+0.01)+ba
    vb = mb*(xint+0.01)+bb
    if vb > va:
        xints.append((xint,val,na,nb))
    else:
        xints.append((xint,val,nb,na))

これにより、36の交差点が生成され、そのほとんどが冗長になります。その時点で、他のカットの方が価値があります。したがって、次のようにフィルタリングします。

xints = [(xint,val,na,nb) for xint,val,na,nb in xints if all(nc==na or nc==nb or mc*xint+bc <= val for nc,mc,bc in cuts)]
xints.sort()

これにより、10個の有効な交差点が残ります。

[
    (40.0, 0.0, 'Emerald', 'Oval'),
    (60.0, 10.0, 'Oval', 'Pear'),
    (60.0, 10.0, 'Oval', 'Plumbbob'),
    (60.0, 10.0, 'Pear', 'Plumbbob'),
    (83.33333333333331, 33.333333333333314, 'Marquis', 'Crystal Ball'),
    (83.33333333333331, 33.333333333333314, 'Plumbbob', 'Crystal Ball'),
    (83.33333333333331, 33.333333333333314, 'Plumbbob', 'Marquis'),
    (166.66666666666669, 166.66666666666674, 'Crystal Ball', 'Brilliant'),
    (300.0, 500.0, 'Brilliant', 'Star Cut'),
    (600.0, 1400.0, 'Star Cut', 'Heart-shaped')
]

検査により、PearとMarquisのカットは冗長であることがわかります-それらは交点でのみ正確に競争力があります-したがって、それらが表示される4つのアイテムを破棄し、

[
    (40.0, 0.0, 'Emerald', 'Oval'),
    (60.0, 10.0, 'Oval', 'Plumbbob'),
    (83.33333333333331, 33.333333333333314, 'Plumbbob', 'Crystal Ball'),
    (166.66666666666669, 166.66666666666674, 'Crystal Ball', 'Brilliant'),
    (300.0, 500.0, 'Brilliant', 'Star Cut'),
    (600.0, 1400.0, 'Star Cut', 'Heart-shaped')
]

最適な交差点です。その後、あなたのテーブルは次のようになります

Size      Value      Cut
----      -----     ------------
   0       -10
                    Emerald
  40         0
                    Oval
  60        10
                    Plumbbob
  83.33     33.33
                    Crystal Ball
 166.67    166.67
                    Brilliant
 300       500
                    Star Cut
 600      1400
                    Heart-shaped

厳密に言えば、期待値が負であるため、おそらくエメラルドカットを破棄できます(40未満の宝石をカットするとお金が失われます)。

于 2012-06-25T02:24:12.370 に答える
1
def create_table():
    curname = None
    for amount in xrange(2500):
        name = best(amount)
        if name != curname:
            if curname is not None:
                print "%d-%d %s" % (minamt, amount-1, curname)
            curname = name
            minamt = amount
    print "%d-%d %s" % (minamt, amount-1, curname)

(テストされていません、ところで)

于 2012-06-25T00:43:05.933 に答える