Esempio n. 1
0
 def _breed_new_ai(self, cursor, old_player_ids):
     """Breed a new AI, from two weighted-random experienced parents."""
     query = """SELECT p.player_id, p.mu FROM player p
                WHERE p.class = 'CleverBot'"""
     cursor.execute(query)
     rows = cursor.fetchall()
     possible_parents = []
     for row in rows:
         mu = row["mu"]
         player_id = row["player_id"]
         if player_id in old_player_ids:
             possible_parents.append((mu, player_id))
     tup1 = Dice.weighted_random_choice(possible_parents)
     possible_parents.remove(tup1)
     tup2 = Dice.weighted_random_choice(possible_parents)
     player_id1 = tup1[1]
     info1 = self.get_player_info(player_id1)
     bp1 = BotParams.BotParams.fromstring(info1)
     player_id2 = tup2[1]
     info2 = self.get_player_info(player_id2)
     bp2 = BotParams.BotParams.fromstring(info2)
     bp3 = bp1.cross(bp2).mutate_random_field()
     bot = CleverBot.CleverBot("child", config.DEFAULT_AI_TIME_LIMIT, bp3)
     info = bot.player_info
     logging.info("player_info %s", info)
     query = """INSERT INTO player (class, info, mu, sigma)
                VALUES (?, ?, ?, ?)"""
     cursor.execute(query, ("CleverBot", info, DEFAULT_MU, DEFAULT_SIGMA))
     # And fetch the player_id.
     query = """SELECT player_id FROM player
                where class = ? AND info = ?"""
     cursor.execute(query, ("CleverBot", info))
     row = cursor.fetchone()
     player_id = row["player_id"]
     # And update the name.
     name = "ai%d" % player_id
     query = """UPDATE player SET name = ?
                WHERE player_id = ?"""
     cursor.execute(query, (name, player_id))
     logging.info("father %s %s", player_id1, bp1)
     logging.info("mother %s %s", player_id2, bp2)
     logging.info("baby %s %s %s", player_id, name, bp3)
     return player_id
Esempio n. 2
0
 def _breed_new_ai(self, cursor, old_player_ids):
     """Breed a new AI, from two weighted-random experienced parents."""
     query = """SELECT p.player_id, p.mu FROM player p
                WHERE p.class = 'CleverBot'"""
     cursor.execute(query)
     rows = cursor.fetchall()
     possible_parents = []
     for row in rows:
         mu = row["mu"]
         player_id = row["player_id"]
         if player_id in old_player_ids:
             possible_parents.append((mu, player_id))
     tup1 = Dice.weighted_random_choice(possible_parents)
     possible_parents.remove(tup1)
     tup2 = Dice.weighted_random_choice(possible_parents)
     player_id1 = tup1[1]
     info1 = self.get_player_info(player_id1)
     bp1 = BotParams.BotParams.fromstring(info1)
     player_id2 = tup2[1]
     info2 = self.get_player_info(player_id2)
     bp2 = BotParams.BotParams.fromstring(info2)
     bp3 = bp1.cross(bp2).mutate_random_field()
     bot = CleverBot.CleverBot("child", config.DEFAULT_AI_TIME_LIMIT, bp3)
     info = bot.player_info
     logging.info("player_info %s", info)
     query = """INSERT INTO player (class, info, mu, sigma)
                VALUES (?, ?, ?, ?)"""
     cursor.execute(query, ("CleverBot", info, DEFAULT_MU, DEFAULT_SIGMA))
     # And fetch the player_id.
     query = """SELECT player_id FROM player
                where class = ? AND info = ?"""
     cursor.execute(query, ("CleverBot", info))
     row = cursor.fetchone()
     player_id = row["player_id"]
     # And update the name.
     name = "ai%d" % player_id
     query = """UPDATE player SET name = ?
                WHERE player_id = ?"""
     cursor.execute(query, (name, player_id))
     logging.info("father %s %s", player_id1, bp1)
     logging.info("mother %s %s", player_id2, bp2)
     logging.info("baby %s %s %s", player_id, name, bp3)
     return player_id
Esempio n. 3
0
 def test_weighted_random_choice(self):
     lst = [
         (0.4, 1),
         (0.3, 2),
         (0.2, 3),
         (0.1, 4),
     ]
     # Can use a Counter when we require Python 2.7
     counter = defaultdict(int)
     for trial in xrange(1000):
         tup = Dice.weighted_random_choice(lst)
         print tup
         counter[tup[1]] += 1
     print counter
     assert sum(counter.itervalues()) == 1000
     assert counter[1] > counter[2] > counter[3] > counter[4]
Esempio n. 4
0
 def test_weighted_random_choice(self):
     lst = [
         (0.4, 1),
         (0.3, 2),
         (0.2, 3),
         (0.1, 4),
     ]
     # Can use a Counter when we require Python 2.7
     counter = defaultdict(int)
     for trial in xrange(1000):
         tup = Dice.weighted_random_choice(lst)
         print tup
         counter[tup[1]] += 1
     print counter
     assert sum(counter.itervalues()) == 1000
     assert counter[1] > counter[2] > counter[3] > counter[4]
Esempio n. 5
0
    def get_weighted_random_player_id(self, excludes=(), highest_mu=False):
        """Return a player_id.  Exclude any player_ids in excludes.

        If there are fewer than GENERATION_SIZE AI player_id in the database,
        add a new AI (by mutating the default) and return its player_id.

        If highest_mu is not None, then return the eligible player_id with
        the highest mu.

        If there are fewer than GENERATION_SIZE AI player_ids in the database
        with sigma <= BREEDING_SIGMA_THRESHOLD, breed a new AI (by
        crossing two parent AIs with sigma <= BREEDING_SIGMA_THRESHOLD,
        chosen randomly weighted by mu), and return its player_id.

        Otherwise, choose an existing player_id randomly, weighted by low
        sigma, and return it.
        """
        with self.connection:
            cursor = self.connection.cursor()
            total_ai_count = 0

            query = """SELECT player_id, mu, sigma FROM player p
                       WHERE p.class='CleverBot'"""
            cursor.execute(query)
            rows = cursor.fetchall()
            young_player_ids = set()
            old_player_ids = set()
            for row in rows:
                player_id = row["player_id"]
                sigma = row["sigma"]
                if sigma <= BREEDING_SIGMA_THRESHOLD:
                    old_player_ids.add(player_id)
                else:
                    young_player_ids.add(player_id)
            young_ai_count = len(young_player_ids)
            old_ai_count = len(old_player_ids)
            total_ai_count = young_ai_count + old_ai_count

            if highest_mu:
                # Pick the eligible AI with the highest mu and return its
                # player_id.
                query = """SELECT player_id, mu FROM player
                           WHERE class = 'CleverBot'
                           ORDER BY mu DESC"""
                cursor.execute(query)
                rows = cursor.fetchall()
                for row in rows:
                    player_id = row["player_id"]
                    if player_id not in excludes:
                        logging.info("picked high-mu AI %s", player_id)
                        return player_id

            if young_ai_count < GENERATION_SIZE and old_ai_count >= 2:
                # Not enough young AIs, so breed one.
                return self._breed_new_ai(cursor, old_player_ids)

            else:
                candidates = []
                # Pick an existing young AI randomly, weighted by low sigma,
                # and return its player_id.
                query = """SELECT player_id, sigma FROM player
                           WHERE class = 'CleverBot'"""
                cursor.execute(query)
                rows = cursor.fetchall()
                for row in rows:
                    player_id = row["player_id"]
                    sigma = row["sigma"]
                    if player_id in young_player_ids and player_id not in excludes:
                        candidates.append((1.0 / sigma, player_id))
                if candidates:
                    tup = Dice.weighted_random_choice(candidates)
                    player_id = tup[1]
                    logging.info("picked random AI %s", player_id)
                    return player_id
                else:
                    # No eligible AIs available, so either breed or spawn
                    # a new one.
                    if total_ai_count < GENERATION_SIZE:
                        return self._spawn_new_ai(cursor)
                    elif old_ai_count >= 2:
                        return self._breed_new_ai(cursor, old_player_ids)
                    else:
                        return self._spawn_new_ai(cursor)
Esempio n. 6
0
    def get_weighted_random_player_id(self, excludes=(), highest_mu=False):
        """Return a player_id.  Exclude any player_ids in excludes.

        If there are fewer than GENERATION_SIZE AI player_id in the database,
        add a new AI (by mutating the default) and return its player_id.

        If highest_mu is not None, then return the eligible player_id with
        the highest mu.

        If there are fewer than GENERATION_SIZE AI player_ids in the database
        with sigma <= BREEDING_SIGMA_THRESHOLD, breed a new AI (by
        crossing two parent AIs with sigma <= BREEDING_SIGMA_THRESHOLD,
        chosen randomly weighted by mu), and return its player_id.

        Otherwise, choose an existing player_id randomly, weighted by low
        sigma, and return it.
        """
        with self.connection:
            cursor = self.connection.cursor()
            total_ai_count = 0

            query = """SELECT player_id, mu, sigma FROM player p
                       WHERE p.class='CleverBot'"""
            cursor.execute(query)
            rows = cursor.fetchall()
            young_player_ids = set()
            old_player_ids = set()
            for row in rows:
                player_id = row["player_id"]
                sigma = row["sigma"]
                if sigma <= BREEDING_SIGMA_THRESHOLD:
                    old_player_ids.add(player_id)
                else:
                    young_player_ids.add(player_id)
            young_ai_count = len(young_player_ids)
            old_ai_count = len(old_player_ids)
            total_ai_count = young_ai_count + old_ai_count

            if highest_mu:
                # Pick the eligible AI with the highest mu and return its
                # player_id.
                query = """SELECT player_id, mu FROM player
                           WHERE class = 'CleverBot'
                           ORDER BY mu DESC"""
                cursor.execute(query)
                rows = cursor.fetchall()
                for row in rows:
                    player_id = row["player_id"]
                    if player_id not in excludes:
                        logging.info("picked high-mu AI %s", player_id)
                        return player_id

            if young_ai_count < GENERATION_SIZE and old_ai_count >= 2:
                # Not enough young AIs, so breed one.
                return self._breed_new_ai(cursor, old_player_ids)

            else:
                candidates = []
                # Pick an existing young AI randomly, weighted by low sigma,
                # and return its player_id.
                query = """SELECT player_id, sigma FROM player
                           WHERE class = 'CleverBot'"""
                cursor.execute(query)
                rows = cursor.fetchall()
                for row in rows:
                    player_id = row["player_id"]
                    sigma = row["sigma"]
                    if (player_id in young_player_ids
                            and player_id not in excludes):
                        candidates.append((1.0 / sigma, player_id))
                if candidates:
                    tup = Dice.weighted_random_choice(candidates)
                    player_id = tup[1]
                    logging.info("picked random AI %s", player_id)
                    return player_id
                else:
                    # No eligible AIs available, so either breed or spawn
                    # a new one.
                    if total_ai_count < GENERATION_SIZE:
                        return self._spawn_new_ai(cursor)
                    elif old_ai_count >= 2:
                        return self._breed_new_ai(cursor, old_player_ids)
                    else:
                        return self._spawn_new_ai(cursor)