|
I'm not sure how familiar you guys are with the game twenty four, but basically you take 4 numbers and you can use 3 operators (+,-,*,/) in any given order to make those 4 numbers become 24. import random
def bin_2_dec(bina): a = 0 num = 0 for x in bina: if x == "1": num = num + 2 ** a a = a + 1 return num
class TwentyFour: POP_NUM = 30 MUT_RATE = .1 REC_RATE = .5 IDEAL = 24 CHROMES = 12 ARRANGEMENTS = [[0,1,2,3],[0,1,3,2],[0,2,1,3],[0,2,3,1], [0,3,1,2],[0,3,2,1],[1,0,2,3],[1,0,3,2], [1,2,0,3],[1,3,0,2],[2,0,1,3],[2,1,0,3]] OPS = ["+","-","*","/"]
def __init__(self, nums): self.pop = [""] * TwentyFour.POP_NUM self.fill_pop() self.nums = nums def fill_pop(self): for x in range(TwentyFour.POP_NUM): self.pop[x] = self.gen_rand_chromes()
def gen_rand_chromes(self): chromes = "" for x in range(TwentyFour.CHROMES): chromes = chromes + str(random.randint(0,1)) return chromes
def to_string(self, chromes): arrchrome = chromes[0:4] orderchrome = chromes[4] order2chrome = chromes[5]
arr = bin_2_dec(arrchrome) if arr >= 12: arr = arr - 12
arr = TwentyFour.ARRANGEMENTS[arr] op1 = TwentyFour.OPS[bin_2_dec(chromes[6:8])] op2 = TwentyFour.OPS[bin_2_dec(chromes[8:10])] op3 = TwentyFour.OPS[bin_2_dec(chromes[10:12])]
stra = str(self.nums[arr[0]])+op1 if order2chrome == "1": stra = stra + "(" stra = stra + str(self.nums[arr[1]])+op2 if orderchrome == "1": stra = stra + "(" stra = stra + str(self.nums[arr[2]])+op3+str(self.nums[arr[3]]) if orderchrome == "1": stra = stra + ")" if order2chrome == "1": stra = stra + ")" return stra
def compute(self, chromes): astr = self.to_string(chromes) for x in range(1,10): astr = astr.replace(str(x), "float("+str(x)+")") try: return eval(astr) except: return 0
def do_op(self, op, num1, num2): val = eval("float(num1)"+op+"float(num2)") if val < 1: 1/0 return val
def get_error(self, val): return abs(float(val - TwentyFour.IDEAL)/TwentyFour.IDEAL)
def run_trial(self): a = random.randint(0, TwentyFour.POP_NUM-1) b = random.randint(0, TwentyFour.POP_NUM-1)
if a == b: if b == 0: b = b + 1 else: b = b - 1
ac = self.pop[a] bc = self.pop[b]
av = self.compute(ac) bv = self.compute(bc)
if self.get_error(av) < self.get_error(bv): if self.get_error(av) == 0.0: return a winner = a loser = b else: if self.get_error(bv) == 0.0: return b winner = b loser = a
newchromes = self.pop[loser][:] for x in range(TwentyFour.CHROMES): if random.random() < TwentyFour.REC_RATE: newchromes = newchromes[0:x] + \ self.pop[winner][x] + \ newchromes[x+1:]
if random.random() < TwentyFour.MUT_RATE: newchromes = newchromes[0:x] + \ str(1-int(newchromes[x])) + \ newchromes[x+1:]
self.pop[loser] = newchromes
return a
def run_up_to(self, num): for x in range(num): apop = self.run_trial() if self.get_error(self.compute(self.pop[apop])) == 0.0: print "trial " + str(x) print self.to_string(self.pop[apop])+"="+str(self.compute(self.pop[apop])) return if x > num - 10: print "trial " + str(x) print self.to_string(self.pop[apop])+"="+str(self.compute(self.pop[apop])) print "Failed to find answer in "+str(num)+" trials"
nums = [0]*4 for x in range(4): a = 0 while a < 1 or a > 9: a = input("Enter a number: ") try: a * 2 except: a = 0 nums[x] = a
t4 = TwentyFour(nums) t4.run_up_to(10000) I wrote this sort of half-assedly. I'm wondering if there are any problems that it's unable to find a solution for that actually have a solution.
Last Edit: Oct 30, 2009 18:42:55 GMT by Eric
|
|
|