Commits

dan mackinlay committed c49461d

numerous fixes to make the bloody thing actually go; this is now approximately Bob's original idea

  • Participants
  • Parent commits 6dab628

Comments (0)

Files changed (5)

privateer_pyevolve/lotteries.py

+#!/usr/bin/env python
+# encoding: utf-8
+"""
+market.py
+
+Created by dan mackinlay on 2010-09-24.
+Copyright (c) 2010 __MyCompanyName__. All rights reserved.
+"""
+
+import random  
+from math import sqrt
+DEFAULT_RNG = random.Random()
+
+
+class Lottery(dict):
+    """
+    A namespace into which to stash information about this particular type of lottery. Lotteries are just dicts of fn variables
+    """
+    def __init__(self, *args, **kwargs):
+        super(Lottery, self).__init__(*args, **kwargs)
+    
+    def decide(self, *args, **kwargs):
+        raise NotImplementedError
+    
+    def std_dev(self, *args, **kwargs):
+        raise NotImplementedError
+    
+    def expectation(self, *args, **kwargs):
+        raise NotImplementedError
+
+class WeightedCoinToss(Lottery):
+    """
+    toss a biased coin and return either the lower or upper bound
+    should have keys of 'upper', 'lower' and 0<'lowerweight'<1
+    """
+        
+    def decide(self, *args, **kwargs):
+        rng = self.get('rng', DEFAULT_RNG)
+        return self['lower'] if rng.random()<self['lowerweight'] else self['upper']
+    
+    def expectation(self, *args, **kwargs):
+        return (self['lower']*self['lowerweight'] +
+           self['upper']*(1-self['lowerweight']))
+
+class UniformLottery(Lottery):
+    """
+    toss a coin and return either the lower or upper bound
+    should have keys.upper and keys.lower
+    
+    Not currently used
+    """
+    def decide(self, *args, **kwargs):
+        rng = self.get('rng', DEFAULT_RNG)
+        return rng.random()*(self['upper']-self['lower'])+self['lower']
+    
+    def std_dev(self, *args, **kwargs):
+        return (self['upper'] - self['lower'])/(2.0*sqrt(3))
+    
+    def expectation(self, *args, **kwargs):
+        return (self['lower']+self['lower'])*0.5
+
+
+def get_lottery(max_abs_prize_val=100, rng=None):
+    if rng is None:
+        rng=DEFAULT_RNG
+    return WeightedCoinToss(
+        lower=max_abs_prize_val*(2*rng.random()-1),
+        upper=max_abs_prize_val*(2*rng.random()-1),
+        lowerweight=rng.random()
+    )
+
+      
+    
+    

privateer_pyevolve/lottery.py

-#!/usr/bin/env python
-# encoding: utf-8
-"""
-market.py
-
-Created by dan mackinlay on 2010-09-24.
-Copyright (c) 2010 __MyCompanyName__. All rights reserved.
-"""
-
-import random  
-from math import sqrt
-DEFAULT_RNG = random.Random()
-
-
-class Lottery(dict):
-    """
-    A namespace into which to stash information about this particular type of lottery. Lotteries are just dicts of fn variables
-    """
-    def __init__(self, *args, **kwargs):
-        super(Lottery, self).__init__(*args, **kwargs)
-    
-    def decide(self, *args, **kwargs):
-        raise NotImplementedError
-    
-    def std_dev(self, *args, **kwargs):
-        raise NotImplementedError
-    
-    def expectation(self, *args, **kwargs):
-        raise NotImplementedError
-
-class WeightedCoinToss(Lottery):
-    """
-    toss a biased coin and return either the lower or upper bound
-    should have keys of 'upper', 'lower' and 0<'lowerweight'<1
-    """
-        
-    def decide(self, *args, **kwargs):
-        rng = self.get('rng', DEFAULT_RNG)
-        return self['lower'] if rng.random()<self['lowerweight'] else self['upper']
-    
-    def expectation(self, *args, **kwargs):
-        return (self['lower']*self['lowerweight'] +
-           self['upper']*(1-self['lowerweight']))
-
-class UniformLottery(Lottery):
-    """
-    toss a coin and return either the lower or upper bound
-    should have keys.upper and keys.lower
-    
-    Not currently used
-    """
-    def decide(self, *args, **kwargs):
-        rng = self.get('rng', DEFAULT_RNG)
-        return rng.random()*(self['upper']-self['lower'])+self['lower']
-    
-    def std_dev(self, *args, **kwargs):
-        return (self['upper'] - self['lower'])/(2.0*sqrt(3))
-    
-    def expectation(self, *args, **kwargs):
-        return (self['lower']+self['lower'])*0.5
-
-
-def get_lottery(max_abs_prize_val=100, rng=None):
-    if rng is None:
-        rng=DEFAULT_RNG
-    return WeightedCoinToss(
-        lower=max_abs_prize_val*(2*rng.random()-1),
-        upper=max_abs_prize_val*(2*rng.random()-1),
-        lowerweight=rng.random()
-    )
-
-      
-    
-    

privateer_pyevolve/market.py

+import lotteries
+import privateers
+
+def value_of_one_trade(trader):
+    "one round of market trading"
+    lottery = trader.choose_lottery([lotteries.get_lottery() for i in range(2)])
+    return lottery.decide()
+
+def value_of_lifetime(genome, Klass=privateers.CARATrader, rounds=10):
+    "several rounds of market trading"
+    trader = Klass(genome)
+    for round in range(rounds):
+        trader.wealth += value_of_one_trade(trader)
+    return trader.wealth

privateer_pyevolve/privateer_sim.py

 from pyevolve import Selectors
 from pyevolve import Statistics
 # from pyevolve import DBAdapters
-from pyevolve import Selectors, Crossovers, Consts, Initializators, Mutators
+from pyevolve import Selectors, Crossovers, Consts, Initializators, Mutators, Scaling
 
-def eval_func(genome):
-    """
-    This function is the evaluation function, we want
-    to give high score to more zero'ed chromosomes
-
-        :param genome: Genome list.
-        :type name: Genome1d.
-        :returns:  int -- the return code.      
-        :raises: AttributeError, KeyError
-
-        """
-    return sum([abs(s) for s in genome])
+import market
 
 def run_main():
     # Genome instance, 1D List of 50 elements
     genome.setParams(rangemin=-2.0, rangemax=2.0)
 
     # The evaluator function (evaluation function)
-    genome.evaluator.set(eval_func)
+    genome.evaluator.set(market.value_of_lifetime)
     
     # Mutator function 
     genome.mutator.set(Mutators.G1DListMutatorRealGaussian)
     ga.selector.set(Selectors.GRouletteWheel)
     ga.setGenerations(500)
     ga.terminationCriteria.set(GSimpleGA.ConvergenceCriteria)
-    ga.setMinimax(Consts.minimaxType["minimize"])
+    ga.setMinimax(Consts.minimaxType["maximize"])
+    
+    pop = ga.getPopulation()
+    pop.scaleMethod.set(Scaling.SigmaTruncScaling)
     
     # # Sets the DB Adapter, the resetDB flag will make the Adapter recreate
     # # the database and erase all data every run, you should use this flag

privateer_pyevolve/privateers.py

+from math import exp
+
+class Trader(object):
+    """encapsulate trader logic"""
+    def __init__(self, genome, *args, **kwargs):
+        super(Trader, self).__init__(*args, **kwargs)
+        self.genome = genome
+        self.wealth = 0
+    
+    def utility_of_lottery(self, lottery):
+        raise NotImplementedError
+    
+    def choose_lottery(self, lottery_list):
+        """look through a list of lotteries and choose the best one by my
+        utility function
+        
+        In fact, although this is written for arbitrary lists, it shouldn't be
+        used for lists of length>2, since that reduces selection pressure on
+        the utility function. Pfff."""
+        chosen = lottery_list.pop()
+        best_utility = self.utility_of_lottery(chosen)
+        for next_lottery in lottery_list:
+            next_utility = self.utility_of_lottery(next_lottery)
+            if next_utility>best_utility:
+                best_utility = next_utility
+                chosen = next_lottery
+        return chosen
 
 """;;; Bob Mark's reference impementation of CARA payoff values from
 ;;; http://www.agsm.edu.au/bobm/teaching/SimSS/NetLogo4-models/RA-CARA-EU-3l2p.html
    
 end"""
 
-class CARATrader(object):
+class CARATrader(Trader):
     """encapsulate trader logic"""
-    def __init__(self, genome, *args, **kwargs):
-        super(Trader, self).__init__(*args, **kwargs)
-        self.genome = genome
     
     def utility_of_lottery(self, lottery):
         return cara_utility_of_lottery(self.genome, lottery)
-    
-    def choose_lottery(lottery_list):
-        """look through a list of lotteries and choose the best one by my
-        utility function
-        
-        In fact, although this is written for arbitrary lists, it shouldn't be
-        used for lists of length>2, since that reduces selection pressure on
-        the utility function. Pfff."""
-        chosen = lottery_list.pop()
-        best_utility = self.utility_of_lottery(chosen)
-        for next_lottery in lottery_list:
-            next_utility = self.utility_of_lottery(next_lottery)
-            if next_utility>best_utility:
-                best_utility = next_utility
-                chosen = next_lottery
-        return chosen
 
 def cara_utility_of_prize(gamma, prize):
-    return (1.0 - e**(-gamma * prize))
+    return (1.0 - exp(-gamma * prize))
 
 def cara_utility_of_lottery(genome, lottery):
     [gamma] = genome
-    return cara_utility_of_prize(lottery['lower']) * lottery['lowerweight'] +\
-      cara_utility_of_prize(lottery['upper']) * (1.0-lottery['lowerweight'])
+    return cara_utility_of_prize(gamma, lottery['lower']) *\
+       lottery['lowerweight'] +\
+           cara_utility_of_prize(gamma, lottery['upper']) *\
+       (1.0-lottery['lowerweight'])
 
 
 
      [(item 1 lot3) ]]
    
 end"""
+