結果
問題 | No.286 Modulo Discount Store |
ユーザー | Tatamo |
提出日時 | 2016-07-20 13:01:12 |
言語 | Python2 (2.7.18) |
結果 |
WA
|
実行時間 | - |
コード長 | 4,694 bytes |
コンパイル時間 | 124 ms |
コンパイル使用メモリ | 7,168 KB |
実行使用メモリ | 7,424 KB |
最終ジャッジ日時 | 2024-10-15 17:34:30 |
合計ジャッジ時間 | 4,211 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 49 ms
7,040 KB |
testcase_01 | WA | - |
testcase_02 | WA | - |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | AC | 48 ms
7,040 KB |
testcase_06 | WA | - |
testcase_07 | AC | 38 ms
7,040 KB |
testcase_08 | AC | 45 ms
6,912 KB |
testcase_09 | AC | 48 ms
6,912 KB |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | AC | 49 ms
7,040 KB |
testcase_15 | AC | 42 ms
6,912 KB |
testcase_16 | WA | - |
testcase_17 | WA | - |
testcase_18 | WA | - |
testcase_19 | AC | 41 ms
6,912 KB |
testcase_20 | WA | - |
testcase_21 | AC | 53 ms
7,168 KB |
testcase_22 | WA | - |
testcase_23 | WA | - |
testcase_24 | WA | - |
testcase_25 | WA | - |
testcase_26 | AC | 41 ms
7,040 KB |
testcase_27 | WA | - |
testcase_28 | WA | - |
testcase_29 | AC | 49 ms
7,040 KB |
testcase_30 | AC | 49 ms
7,168 KB |
testcase_31 | WA | - |
testcase_32 | WA | - |
testcase_33 | WA | - |
testcase_34 | AC | 52 ms
7,040 KB |
testcase_35 | WA | - |
testcase_36 | AC | 37 ms
6,912 KB |
testcase_37 | WA | - |
testcase_38 | AC | 44 ms
7,040 KB |
testcase_39 | WA | - |
testcase_40 | AC | 45 ms
7,040 KB |
testcase_41 | AC | 45 ms
7,040 KB |
testcase_42 | AC | 53 ms
7,040 KB |
ソースコード
# coding: utf-8 import random # GA n = input() m = [] for i in range(n): m.append((i,input())) def generateGene(): tmp = [] table = m[:] for x in xrange(n): i = random.randint(0,len(table)-1) tmp.append(table[i]) del(table[i]) return tmp class Individual: def __init__(self, gene): self.gene = gene self.value = 0 self.eval() def eval(self): discount = 0 self.value = 0 for id,c in self.gene: self.value += max(c-discount,0) discount = (discount+c)%1000 class Solver: def __init__(self, data): self.NUM_POP = 30 # 少なくとも2以上かつ偶数にして self.GENERATION = 100 self.MUTANTRATE_RATE = 30 # ‰ self.data = data def mutantrate(self, pop): # 突然変異を発生させる for s in pop: rand = random.randint(1,1000) if(rand <= self.MUTANTRATE_RATE): # ランダムな遺伝子2つを入れ替える a,b = (random.randint(0,len(self.data)-1),random.randint(0,len(self.data)-1)) # 選択位置が重複しないとは言っていない tmp = s.gene[a] s.gene[a] = s.gene[b] s.gene[b] = tmp s.eval() def crossover(self, pop, prob_table): # 2個体pickする count = 0 prob_sum = sum(prob_table) r1 = random.randint(0, prob_sum) r2 = random.randint(0, prob_sum) parent1 = parent2 = None for i,s in enumerate(pop): count += prob_table[i] if(count>=r1): parent1 = s if(count>=r2): parent2 = s if(parent1 != None and parent2 != None): break return self.pmx(parent1, parent2) #Partially-mapped crossover http://homepage3.nifty.com/ono-t/GA/GA-order.html#PMX def pmx(self, parent1, parent2): a,b = (random.randint(0,len(self.data)),random.randint(0,len(self.data))) first, second = min(a,b), max(a,b) child1 = Individual(parent1.gene[:]) child2 = Individual(parent2.gene[:]) # まず選択部分を交叉する for i in xrange(first, second): child1.gene[i] = parent2.gene[i] child2.gene[i] = parent1.gene[i] c1m = child1.gene[first:second] c2m = child2.gene[first:second] # 交叉対象に含まれた要素を、対応する要素に変更する for i in xrange(len(self.data)): for ii in xrange(second-first): if(child1.gene[i] == c1m[ii]): child1.gene[i] = c2m[ii] if(child2.gene[i] == c2m[ii]): child2.gene[i] = c1m[ii] child1.eval() child2.eval() return (child1, child2) def solve(self): # 最初の個体群をランダム生成 pop = [Individual(generateGene()) for x in xrange(self.NUM_POP)] for gc in xrange(self.GENERATION): min_val = sum([c for i, c in self.data]) max_val = -1 top_index = -1 top2_index = -1 # 評価補助テーブル生成 for i,s in enumerate(pop): # print "max:" , max_val, "min:", min_val, ",", s.gene, s.value if(s.value < min_val): min_val = s.value top2_index = top_index top_index = i if(s.value > max_val): max_val = s.value pickup_table = [0]*len(self.data) for i in xrange(len(self.data)): pickup_table[i] = max_val - pop[i].value + 1 # 0にならないよう1足す #print pickup_table # 評価の高さに基づいた確率により個体を交叉させ新個体を生成 left = self.NUM_POP - 2 top_s = Individual([]) top_s.gene = pop[top_index].gene[:] top_s.eval() top2_s = Individual([]) top2_s.gene = pop[top2_index].gene[:] top2_s.eval() # トップ2個体はそのまま残す new_pop = [top_s, top2_s] while(left>0): new_pop += self.crossover(pop, pickup_table) # 生成した新個体をテーブルに追加 left -= 2 # 突然変異 self.mutantrate(new_pop) pop = new_pop top = pop[0] for s in pop: #print s.gene if(s.value < top.value): top = s print top.value Solver(m).solve()