def getRealAction_real(self, state, actVars=None):
        Program.execute(state, self.registers, self.program.instructions[:, 0],
                        self.program.instructions[:, 1],
                        self.program.instructions[:, 2],
                        self.program.instructions[:, 3])

        return self.registers[:self.actionLength]
Beispiel #2
0
    def init_def(self, initParams, program, actionObj, numRegisters, learner_id=None):
        self.program = Program(
            instructions=program.instructions
        ) #Each learner should have their own copy of the program
        self.actionObj = ActionObject(action=actionObj, initParams=initParams) #Each learner should have their own copy of the action object
        self.registers = np.zeros(numRegisters, dtype=float)

        self.ancestor = None #By default no ancestor

        '''
        TODO What's self.states? 
        '''
        self.states = []


        self.inTeams = [] # Store a list of teams that reference this learner, incoming edges
        

        self.genCreate = initParams["generation"] # Store the generation that this learner was created on

        '''
        TODO should this be -1 before it sees any frames?
        '''
        self.frameNum = 0 # Last seen frame is 0

        # Assign id from initParams counter
        self.id = uuid.uuid4()


        if not self.isActionAtomic():
            self.actionObj.teamAction.inLearners.append(str(self.id))
Beispiel #3
0
    def bid(self, state, memMatrix):
        Program.execute(state, self.registers, self.program.instructions[:, 0],
                        self.program.instructions[:, 1],
                        self.program.instructions[:, 2],
                        self.program.instructions[:, 3], memMatrix,
                        memMatrix.shape[0], memMatrix.shape[1])

        return self.registers[0]
    def getRealAction_real_mem(self, state, actVars=None):
        Program.execute(state, self.registers, self.program.instructions[:, 0],
                        self.program.instructions[:, 1],
                        self.program.instructions[:, 2],
                        self.program.instructions[:, 3], actVars["memMatrix"],
                        actVars["memMatrix"].shape[0],
                        actVars["memMatrix"].shape[1],
                        Program.memWriteProbFunc)

        return self.registers[:self.actionLength]
Beispiel #5
0
    def bid_def(self, state, actVars=None):
        # exit early if we already got bidded this frame
        if self.frameNum == actVars["frameNum"]:
            return self.registers[0]

        self.frameNum = actVars["frameNum"]

        Program.execute(state, self.registers,
                        self.program.instructions[:,0], self.program.instructions[:,1],
                        self.program.instructions[:,2], self.program.instructions[:,3])

        return self.registers[0]
Beispiel #6
0
    def initializePopulations(self):
        for i in range(self.teamPopSize):
            # create 2 unique actions and learners
            a1,a2 = random.sample(range(len(self.actionCodes)), 2)

            l1 = Learner(self.mutateParams,
                        program=Program(maxProgramLength=self.initMaxProgSize,
                                         nOperations=self.nOperations,
                                         nDestinations=self.nRegisters,
                                         inputSize=self.inputSize,
                                         initParams=self.mutateParams),
                        actionObj=ActionObject(action=a1, initParams=self.mutateParams),
                        numRegisters=self.nRegisters)
            l2 = Learner(self.mutateParams,
                        program=Program(maxProgramLength=self.initMaxProgSize,
                                         nOperations=self.nOperations,
                                         nDestinations=self.nRegisters,
                                         inputSize=self.inputSize,
                                         initParams=self.mutateParams),
                        actionObj=ActionObject(action=a2, initParams=self.mutateParams),
                        numRegisters=self.nRegisters)

            # save learner population
            self.learners.append(l1)
            self.learners.append(l2)

            # create team and add initial learners
            team = Team(initParams=self.mutateParams)
            team.addLearner(l1)
            team.addLearner(l2)

            # add more learners
            moreLearners = random.randint(0, self.initMaxTeamSize-2)
            for i in range(moreLearners):
                # select action
                act = random.choice(range(len(self.actionCodes)))

                # create new learner
                learner = Learner(initParams=self.mutateParams,
                            program=Program(maxProgramLength=self.initMaxProgSize,
                                             nOperations=self.nOperations,
                                             nDestinations=self.nRegisters,
                                             inputSize=self.inputSize,
                                             initParams=self.mutateParams),
                            actionObj=ActionObject(action=act, initParams=self.mutateParams),
                            numRegisters=self.nRegisters)

                team.addLearner(learner)
                self.learners.append(learner)

            # save to team populations
            self.teams.append(team)
            self.rootTeams.append(team)
Beispiel #7
0
    def test_mutate(self):

        # vars for the test and defining programs
        progs = 100
        muts = 100
        prog_len = 100
        ops = 5
        dests = 8
        inputs = 10000

        # needed for mutation and initialization
        mutateParams = {
            'pProgMut': 0.5,
            'nOperations': ops,
            'nDestinations': dests,
            'inputSize': inputs,
            'pInstDel': 0.5,
            'pInstMut': 0.5,
            'pInstSwp': 0.5,
            'pInstAdd': 0.5,
            'idCountProgram': 0
        }

        # mutate all the progs many times
        for i in range(progs):
            p = Program(maxProgramLength=100,
                        nOperations=ops,
                        nDestinations=dests,
                        inputSize=inputs,
                        initParams=mutateParams)
            for i in range(muts):
                p.mutate(mutateParams)

            # check for program validity
            # atleast 1 instruction
            self.assertGreaterEqual(len(p.instructions), 1)
            # make sure each value in each intex within proper range
            for inst in p.instructions:
                # mode
                self.assertGreaterEqual(inst[0], 0)
                self.assertLessEqual(inst[0], 1)
                # op
                self.assertGreaterEqual(inst[1], 0)
                self.assertLessEqual(inst[1], ops - 1)
                # dest
                self.assertGreaterEqual(inst[2], 0)
                self.assertLessEqual(inst[2], dests - 1)
                # input
                self.assertGreaterEqual(inst[3], 0)
                self.assertLessEqual(inst[3], inputs - 1)
Beispiel #8
0
    def bid_mem(self, state, actVars=None):
        # exit early if we already got bidded this frame
        if self.frameNum == actVars["frameNum"]:
            return self.registers[0]

        self.frameNum = actVars["frameNum"]

        Program.execute(state, self.registers,
                        self.program.instructions[:,0], self.program.instructions[:,1],
                        self.program.instructions[:,2], self.program.instructions[:,3],
                        actVars["memMatrix"], actVars["memMatrix"].shape[0], actVars["memMatrix"].shape[1],
                        Program.memWriteProbFunc)

        return self.registers[0]
Beispiel #9
0
    def configFunctions(self):
        # first set up Agent functions
        Agent.configFunctions(self.functionsDict["Agent"])

        # set up Team functions
        Team.configFunctions(self.functionsDict["Team"])

        # set up Learner functions
        Learner.configFunctions(self.functionsDict["Learner"])

        # set up ActionObject functions
        ActionObject.configFunctions(self.functionsDict["ActionObject"])

        # set up Program functions
        Program.configFunctions(self.functionsDict["Program"])
Beispiel #10
0
def create_dummy_program():
    program = Program(maxProgramLength=128,
                      nOperations=7,
                      nDestinations=8,
                      inputSize=100,
                      initParams=dummy_init_params)
    return program
Beispiel #11
0
    def initializePopulations(self, initMaxTeamSize, initMaxProgSize,
                              registerSize):
        for i in range(self.teamPopSize):
            # create 2 unique actions and learners
            if self.multiAction == False:
                a1, a2 = random.sample(self.actions, 2)
            else:
                a1 = [random.uniform(0, 1) for _ in range(self.actions)]
                a2 = [random.uniform(0, 1) for _ in range(self.actions)]
            l1 = Learner(program=Program(maxProgramLength=initMaxProgSize),
                         action=a1,
                         numRegisters=registerSize)
            l2 = Learner(program=Program(maxProgramLength=initMaxProgSize),
                         action=a2,
                         numRegisters=registerSize)

            # save learner population
            self.learners.append(l1)
            self.learners.append(l2)

            # create team and add initial learners
            team = Team()
            team.addLearner(l1)
            team.addLearner(l2)

            # add more learners
            moreLearners = random.randint(0, initMaxTeamSize - 2)
            for i in range(moreLearners):
                # select action
                if self.multiAction == False:
                    act = random.choice(self.actions)
                else:
                    act = [random.uniform(0, 1) for _ in range(self.actions)]
                # create new learner
                learner = Learner(
                    program=Program(maxProgramLength=initMaxProgSize),
                    action=act,
                    numRegisters=registerSize)
                team.addLearner(learner)
                self.learners.append(learner)

            # save to team populations
            self.teams.append(team)
            self.rootTeams.append(team)
Beispiel #12
0
    def configFunctionsSelf(self):
        from tpg.team import Team
        from tpg.learner import Learner
        from tpg.action_object import ActionObject
        from tpg.program import Program

        # first set up Agent functions
        Agent.configFunctions(self.functionsDict["Agent"])

        # set up Team functions
        Team.configFunctions(self.functionsDict["Team"])

        # set up Learner functions
        Learner.configFunctions(self.functionsDict["Learner"])

        # set up ActionObject functions
        ActionObject.configFunctions(self.functionsDict["ActionObject"])

        # set up Program functions
        Program.configFunctions(self.functionsDict["Program"])
Beispiel #13
0
    def getLearnersInsOuts(self, learners, clearStates=True):
        inputs = []
        outputs = []
        for lrnr in learners:
            lrnrInputs = []
            lrnrOutputs = []
            for state in lrnr.states:
                regs = np.zeros(len(lrnr.registers))
                Program.execute(state, regs, lrnr.program.modes,
                                lrnr.program.operations,
                                lrnr.program.destinations,
                                lrnr.program.sources)
                lrnrInputs.append(state)
                lrnrOutputs.append(regs[0])

            if clearStates:  # free up some space
                lrnr.states = []

            inputs.append(lrnrInputs)
            outputs.append(lrnrOutputs)

        return inputs, outputs
Beispiel #14
0
    def __init__(self,
                 learner=None,
                 program=None,
                 action=None,
                 numRegisters=8):
        if learner is not None:
            self.program = Program(instructions=learner.program.instructions)
            self.action = learner.action
            self.registers = np.zeros(len(learner.registers), dtype=float)
        elif program is not None and action is not None:
            self.program = program
            self.action = action
            self.registers = np.zeros(numRegisters, dtype=float)

        if not self.isActionAtomic():
            self.action.numLearnersReferencing += 1

        self.states = []

        self.numTeamsReferencing = 0  # amount of teams with references to this

        self.id = Learner.idCount
Beispiel #15
0
    def test_max_length(self):

        # Define the number of programs to create and the maximum length of
        # these programs.
        num_attempts = 1000
        max_length = 128

        # needed for mutation and initialization
        mutateParams = {'idCountProgram': 0}

        for i in range(num_attempts):
            with self.subTest():
                p = Program(maxProgramLength=max_length,
                            initParams=mutateParams)
                self.assertLessEqual(np.shape(p.instructions)[0], max_length)
                self.assertTrue(isinstance(p.id, uuid.UUID))
Beispiel #16
0
    def init_real(self, initParams=None, action=None):
        '''
        Defer importing the Team class to avoid circular dependency.
        This may require refactoring to fix properly
        '''
        from tpg.team import Team

        if isinstance(action, Team):
            # The action is a team
            self.actionCode = None
            self.actionLength = None
            self.teamAction = action
            self.program = Program(
                initParams=initParams,
                maxProgramLength=initParams["initMaxActProgSize"],
                nOperations=initParams["nOperations"],
                nDestinations=initParams["nDestinations"],
                inputSize=initParams["inputSize"])

        elif isinstance(action, ActionObject):
            # The action is another action object
            self.actionCode = action.actionCode
            self.actionLength = action.actionLength
            self.teamAction = action.teamAction
            self.program = Program(instructions=action.program.instructions,
                                   initParams=initParams)

        elif isinstance(action, int):
            # An int means the action is an index into the action codes in initParams

            if "actionCodes" not in initParams:
                raise Exception('action codes not found in init params',
                                initParams)

            try:
                self.actionCode = initParams["actionCodes"][action]
                self.actionLength = initParams["actionLengths"][action]
                self.teamAction = None
                self.program = Program(
                    initParams=initParams,
                    maxProgramLength=initParams["initMaxActProgSize"],
                    nOperations=initParams["nOperations"],
                    nDestinations=initParams["nDestinations"],
                    inputSize=initParams["inputSize"])
            except IndexError as err:
                '''
                TODO log index error
                '''
                print("Index error")

        self.registers = np.zeros(
            max(initParams["nActRegisters"], initParams["nDestinations"]))
Beispiel #17
0
    def test_basic_init(self):

        max_length = 128

        # Assert that the id count starts at 0
        #self.assertEqual(0, Program.idCount)

        # needed for mutation and initialization
        mutateParams = {'idCountProgram': 0}

        program = Program(maxProgramLength=max_length, initParams=mutateParams)

        # Assert that, after creating a program the id count has been incremented
        self.assertTrue(isinstance(program.id, uuid.UUID))

        print(np.shape(program.instructions))

        # Assert that the first dimension of the instruction nparray, corresponding to
        # the number of instructions in the program is less than the max program
        # length.
        self.assertLessEqual(np.shape(program.instructions)[0], max_length)
Beispiel #18
0
class Learner:
    def __init__(self,
                 initParams,
                 program,
                 actionObj,
                 numRegisters,
                 learner_id=None):
        self.program = Program(
            instructions=program.instructions
        )  #Each learner should have their own copy of the program
        self.actionObj = ActionObject(
            action=actionObj, initParams=initParams
        )  #Each learner should have their own copy of the action object
        self.registers = np.zeros(numRegisters, dtype=float)

        self.ancestor = None  #By default no ancestor
        '''
        TODO What's self.states? 
        '''
        self.states = []

        self.inTeams = [
        ]  # Store a list of teams that reference this learner, incoming edges

        self.genCreate = initParams[
            "generation"]  # Store the generation that this learner was created on
        '''
        TODO should this be -1 before it sees any frames?
        '''
        self.frameNum = 0  # Last seen frame is 0

        # Assign id from initParams counter
        self.id = uuid.uuid4()

        if not self.isActionAtomic():
            self.actionObj.teamAction.inLearners.append(str(self.id))

        #print("Creating a brand new learner" if learner_id == None else "Creating a learner from {}".format(str(learner_id)))
        #print("Created learner {} [{}] -> {}".format(self.id, "atomic" if self.isActionAtomic() else "Team", self.actionObj.actionCode if self.isActionAtomic() else self.actionObj.teamAction.id))

    def zeroRegisters(self):
        self.registers = np.zeros(len(self.registers), dtype=float)
        self.actionObj.zeroRegisters()

    def numTeamsReferencing(self):
        return len(self.inTeams)

    '''
    A learner is equal to another object if that object:
        - is an instance of the learner class
        - was created on the same generation
        - has an identical program
        - has the same action object
        - has the same inTeams
        - has the same id

    '''

    def __eq__(self, o: object) -> bool:

        # Object must be an instance of Learner
        if not isinstance(o, Learner):
            return False

        # The object must have been created the same generation as us
        if self.genCreate != o.genCreate:
            return False

        # The object's program must be equal to ours
        if self.program != o.program:
            return False

        # The object's action object must be equal to ours
        if self.actionObj != o.actionObj:
            return False
        '''
        The other object's inTeams must match our own, therefore:
            - len(inTeams) must be equal
            - every id that appears in our inTeams must appear in theirs (order doesn't matter)
        '''
        if len(self.inTeams) != len(o.inTeams):
            return False
        '''
        Collection comparison via collection counters
        https://www.journaldev.com/37089/how-to-compare-two-lists-in-python
        '''
        if collections.Counter(self.inTeams) != collections.Counter(o.inTeams):
            return False

        # The other object's id must be equal to ours
        if self.id != o.id:
            return False

        return True

    def debugEq(self, o: object) -> bool:

        # Object must be an instance of Learner
        if not isinstance(o, Learner):
            print("other object is not instance of Learner")
            return False

        # The object must have been created the same generation as us
        if self.genCreate != o.genCreate:
            print("other object has different genCreate")
            return False

        # The object's program must be equal to ours
        if self.program != o.program:
            print("other object has a different program")
            return False

        # The object's action object must be equal to ours
        if self.actionObj != o.actionObj:
            print("other object has a different action object")
            return False
        '''
        The other object's inTeams must match our own, therefore:
            - len(inTeams) must be equal
            - every id that appears in our inTeams must appear in theirs (order doesn't matter)
        '''
        if len(self.inTeams) != len(o.inTeams):
            print("other object has different number of inTeams")
            print("us:")
            print(self)
            print("other learner:")
            print(o)
            return False
        '''
        Collection comparison via collection counters
        https://www.journaldev.com/37089/how-to-compare-two-lists-in-python
        '''
        if collections.Counter(self.inTeams) != collections.Counter(o.inTeams):
            print("other object has different inTeams")
            return False

        # The other object's id must be equal to ours
        if self.id != o.id:
            print("other object has different id")
            return False

        return True

    '''
    Negation of __eq__
    '''

    def __ne__(self, o: object) -> bool:
        return not self.__eq__(o)

    '''
    String representation of a learner
    '''

    def __str__(self):

        result = """id: {}
created_at_gen: {}
program_id: {}
type: {}
action: {}
numTeamsReferencing: {}
inTeams:\n""".format(
            self.id, self.genCreate, self.program.id,
            "actionCode" if self.isActionAtomic() else "teamAction",
            self.actionObj.actionCode
            if self.isActionAtomic() else self.actionObj.teamAction.id,
            self.numTeamsReferencing())

        for cursor in self.inTeams:
            result += "\t{}\n".format(cursor)

        return result

    """
    Create a new learner, either copied from the original or from a program or
    action. Either requires a learner, or a program/action pair.
    """
    """
    Get the bid value, highest gets its action selected.
    """

    def bid(self, state, actVars=None):
        # exit early if we already got bidded this frame
        if self.frameNum == actVars["frameNum"]:
            return self.registers[0]

        self.frameNum = actVars["frameNum"]

        Program.execute(state, self.registers, self.program.instructions[:, 0],
                        self.program.instructions[:, 1],
                        self.program.instructions[:, 2],
                        self.program.instructions[:, 3])

        return self.registers[0]

    """
    Returns the action of this learner, either atomic, or requests the action
    from the action team.
    """

    def getAction(self, state, visited, actVars=None, path_trace=None):
        return self.actionObj.getAction(state,
                                        visited,
                                        actVars=actVars,
                                        path_trace=path_trace)

    """
    Gets the team that is the action of the learners action object.
    """

    def getActionTeam(self):
        return self.actionObj.teamAction

    """
    Returns true if the action is atomic, otherwise the action is a team.
    """

    def isActionAtomic(self):
        return self.actionObj.isAtomic()

    """
    Mutates either the program or the action or both. 
    A mutation creates a new instance of the learner, removes it's anscestor and adds itself to the team.
    """

    def mutate(self, mutateParams, parentTeam, teams, pActAtom):

        changed = False
        while not changed:
            # mutate the program
            if flip(mutateParams["pProgMut"]):

                changed = True

                self.program.mutate(mutateParams)

            # mutate the action
            if flip(mutateParams["pActMut"]):

                changed = True

                self.actionObj.mutate(mutateParams,
                                      parentTeam,
                                      teams,
                                      pActAtom,
                                      learner_id=self.id)

        return self

    """
    Ensures proper functions are used in this class as set up by configurer.
    """

    @classmethod
    def configFunctions(cls, functionsDict):
        from tpg.configuration.conf_learner import ConfLearner

        if functionsDict["init"] == "def":
            cls.__init__ = ConfLearner.init_def

        if functionsDict["bid"] == "def":
            cls.bid = ConfLearner.bid_def
        elif functionsDict["bid"] == "mem":
            cls.bid = ConfLearner.bid_mem

        if functionsDict["getAction"] == "def":
            cls.getAction = ConfLearner.getAction_def

        if functionsDict["getActionTeam"] == "def":
            cls.getActionTeam = ConfLearner.getActionTeam_def

        if functionsDict["isActionAtomic"] == "def":
            cls.isActionAtomic = ConfLearner.isActionAtomic_def

        if functionsDict["mutate"] == "def":
            cls.mutate = ConfLearner.mutate_def
Beispiel #19
0
class Learner:

    idCount = 0  # unique learner id
    """
    Create a new learner, either copied from the original or from a program or
    action. Either requires a learner, or a program/action pair.
    """
    def __init__(self,
                 learner=None,
                 program=None,
                 action=None,
                 numRegisters=8):
        if learner is not None:
            self.program = Program(instructions=learner.program.instructions)
            self.action = learner.action
            self.registers = np.zeros(len(learner.registers), dtype=float)
        elif program is not None and action is not None:
            self.program = program
            self.action = action
            self.registers = np.zeros(numRegisters, dtype=float)

        if not self.isActionAtomic():
            self.action.numLearnersReferencing += 1

        self.states = []

        self.numTeamsReferencing = 0  # amount of teams with references to this

        self.id = Learner.idCount

    """
    Get the bid value, highest gets its action selected.
    """

    def bid(self, state):
        Program.execute(state, self.registers, self.program.modes,
                        self.program.operations, self.program.destinations,
                        self.program.sources)

        return self.registers[0]

    """
    Returns the action of this learner, either atomic, or requests the action
    from the action team.
    """

    def getAction(self, state, visited):
        if self.isActionAtomic():
            return self.action
        else:
            return self.action.act(state, visited)

    """
    Returns true if the action is atomic, otherwise the action is a team.
    """

    def isActionAtomic(self):
        return isinstance(self.action, (int, list))

    """
    Mutates either the program or the action or both.
    """

    def mutate(self,
               pMutProg,
               pMutAct,
               pActAtom,
               atomics,
               parentTeam,
               allTeams,
               pDelInst,
               pAddInst,
               pSwpInst,
               pMutInst,
               multiActs,
               pSwapMultiAct,
               pChangeMultiAct,
               uniqueProgThresh,
               inputs=None,
               outputs=None,
               update=True):

        changed = False
        while not changed:
            # mutate the program
            if flip(pMutProg):
                changed = True
                self.program.mutate(pMutProg,
                                    pDelInst,
                                    pAddInst,
                                    pSwpInst,
                                    pMutInst,
                                    len(self.registers),
                                    uniqueProgThresh,
                                    inputs=inputs,
                                    outputs=outputs,
                                    update=update)

            # mutate the action
            if flip(pMutAct):
                changed = True
                self.mutateAction(pActAtom, atomics, allTeams, parentTeam,
                                  multiActs, pSwapMultiAct, pChangeMultiAct)

    """
    Changes the action, into an atomic or team.
    """

    def mutateAction(self, pActAtom, atomics, allTeams, parentTeam, multiActs,
                     pSwapMultiAct, pChangeMultiAct):
        if not self.isActionAtomic():  # dereference old team action
            self.action.numLearnersReferencing -= 1

        if flip(pActAtom):  # atomic action
            if multiActs is None:
                self.action = random.choice(
                    [a for a in atomics if a is not self.action])
            else:
                swap = flip(pSwapMultiAct)
                if swap or not self.isActionAtomic(
                ):  # totally swap action for another
                    self.action = list(random.choice(multiActs))

                # change some value in action
                if not swap or flip(pChangeMultiAct):
                    changed = False
                    while not changed or flip(pChangeMultiAct):
                        index = random.randint(0, len(self.action) - 1)
                        self.action[index] += random.gauss(0, .15)
                        self.action = list(np.clip(self.action, 0, 1))
                        changed = True

        else:  # Team action
            self.action = random.choice([
                t for t in allTeams
                if t is not self.action and t is not parentTeam
            ])

        if not self.isActionAtomic():  # add reference for new team action
            self.action.numLearnersReferencing += 1

    """
    Saves visited states for mutation uniqueness purposes.
    """

    def saveState(self, state, numStates=50):
        self.states.append(state)
        self.states = self.states[-numStates:]
Beispiel #20
0
class ConfActionObject:
    def init_def(self, initParams=None, action=None):
        '''
        Defer importing the Team class to avoid circular dependency.
        This may require refactoring to fix properly
        '''
        from tpg.team import Team

        # The action is a team
        if isinstance(action, Team):
            self.teamAction = action
            self.actionCode = None
            #print("chose team action")
            return

        # The action is another action object
        if isinstance(action, ActionObject):
            self.actionCode = action.actionCode
            self.teamAction = action.teamAction
            return

        # An int means the action is an index into the action codes in initParams
        if isinstance(action, int):

            if "actionCodes" not in initParams:
                raise Exception('action codes not found in init params',
                                initParams)

            try:
                self.actionCode = initParams["actionCodes"][action]
                self.teamAction = None
            except IndexError as err:
                '''
                TODO log index error
                '''
                print("Index error")
            return

    def init_real(self, initParams=None, action=None):
        '''
        Defer importing the Team class to avoid circular dependency.
        This may require refactoring to fix properly
        '''
        from tpg.team import Team

        if isinstance(action, Team):
            # The action is a team
            self.actionCode = None
            self.actionLength = None
            self.teamAction = action
            self.program = Program(
                initParams=initParams,
                maxProgramLength=initParams["initMaxActProgSize"],
                nOperations=initParams["nOperations"],
                nDestinations=initParams["nDestinations"],
                inputSize=initParams["inputSize"])

        elif isinstance(action, ActionObject):
            # The action is another action object
            self.actionCode = action.actionCode
            self.actionLength = action.actionLength
            self.teamAction = action.teamAction
            self.program = Program(instructions=action.program.instructions,
                                   initParams=initParams)

        elif isinstance(action, int):
            # An int means the action is an index into the action codes in initParams

            if "actionCodes" not in initParams:
                raise Exception('action codes not found in init params',
                                initParams)

            try:
                self.actionCode = initParams["actionCodes"][action]
                self.actionLength = initParams["actionLengths"][action]
                self.teamAction = None
                self.program = Program(
                    initParams=initParams,
                    maxProgramLength=initParams["initMaxActProgSize"],
                    nOperations=initParams["nOperations"],
                    nDestinations=initParams["nDestinations"],
                    inputSize=initParams["inputSize"])
            except IndexError as err:
                '''
                TODO log index error
                '''
                print("Index error")

        self.registers = np.zeros(
            max(initParams["nActRegisters"], initParams["nDestinations"]))

    """
    Returns the action code, and if applicable corresponding real action.
    """

    def getAction_def(self, state, visited, actVars=None, path_trace=None):
        if self.teamAction is not None:
            # action from team
            return self.teamAction.act(state,
                                       visited,
                                       actVars=actVars,
                                       path_trace=path_trace)
        else:
            # atomic action
            return self.actionCode

    """
    Returns the action code, and if applicable corresponding real action(s).
    """

    def getAction_real(self, state, visited, actVars=None, path_trace=None):
        if self.teamAction is not None:
            # action from team
            return self.teamAction.act(state,
                                       visited,
                                       actVars=actVars,
                                       path_trace=path_trace)
        else:
            # atomic action
            if self.actionLength == 0:
                return self.actionCode, None
            else:
                return self.actionCode, self.getRealAction(state,
                                                           actVars=actVars)

    """
    Gets the real action from a register.
    """

    def getRealAction_real(self, state, actVars=None):
        Program.execute(state, self.registers, self.program.instructions[:, 0],
                        self.program.instructions[:, 1],
                        self.program.instructions[:, 2],
                        self.program.instructions[:, 3])

        return self.registers[:self.actionLength]

    """
    Gets the real action from a register. With memory.
    """

    def getRealAction_real_mem(self, state, actVars=None):
        Program.execute(state, self.registers, self.program.instructions[:, 0],
                        self.program.instructions[:, 1],
                        self.program.instructions[:, 2],
                        self.program.instructions[:, 3], actVars["memMatrix"],
                        actVars["memMatrix"].shape[0],
                        actVars["memMatrix"].shape[1],
                        Program.memWriteProbFunc)

        return self.registers[:self.actionLength]

    """
    Returns true if the action is atomic, otherwise the action is a team.
    """

    def isAtomic_def(self):
        return self.teamAction is None

    """
    Change action to team or atomic action.
    """

    def mutate_def(self, mutateParams, parentTeam, teams, pActAtom,
                   learner_id):
        # mutate action
        if flip(pActAtom):
            # atomic
            '''
            If we already have an action code make sure not to pick the same one.
            TODO handle case where there is only 1 action code.
            '''
            if self.actionCode is not None:
                options = list(
                    filter(lambda code: code != self.actionCode,
                           mutateParams["actionCodes"]))
            else:
                options = mutateParams["actionCodes"]

            # let our current team know we won't be pointing to them anymore
            if not self.isAtomic():
                #print("Learner {} switching from Team {} to atomic action".format(learner_id, self.teamAction.id))
                self.teamAction.inLearners.remove(str(learner_id))

            self.actionCode = random.choice(options)
            self.teamAction = None
        else:
            # team action
            selection_pool = [
                t for t in teams
                if t is not self.teamAction and t is not parentTeam
            ]

            # If we have a valid set of options choose from them
            if len(selection_pool) > 0:
                # let our current team know we won't be pointing to them anymore
                oldTeam = None
                if not self.isAtomic():
                    oldTeam = self.teamAction
                    self.teamAction.inLearners.remove(str(learner_id))

                self.teamAction = random.choice(selection_pool)
                # Let the new team know we're pointing to them
                self.teamAction.inLearners.append(str(learner_id))

                #if oldTeam != None:
                #    print("Learner {} switched from Team {} to Team {}".format(learner_id, oldTeam.id, self.teamAction.id))

        return self

    """
    Change action to team or atomic action.
    """

    def mutate_real(self, mutateParams, parentTeam, teams, pActAtom,
                    learner_id):

        # first maybe mutate just program
        if self.actionLength > 0 and flip(0.5):
            self.program.mutate(mutateParams)

        # mutate action
        if flip(pActAtom):
            # atomic
            '''
            If we already have an action code make sure not to pick the same one.
            TODO handle case where there is only 1 action code.
            '''
            if self.actionCode is not None:
                options = list(
                    filter(lambda code: code != self.actionCode,
                           mutateParams["actionCodes"]))
            else:
                options = mutateParams["actionCodes"]

            # let our current team know we won't be pointing to them anymore
            if not self.isAtomic():
                #print("Learner {} switching from Team {} to atomic action".format(learner_id, self.teamAction.id))
                self.teamAction.inLearners.remove(str(learner_id))

            self.actionCode = random.choice(options)
            self.actionLength = mutateParams["actionLengths"][self.actionCode]
            self.teamAction = None
        else:
            # team action
            selection_pool = [
                t for t in teams
                if t is not self.teamAction and t is not parentTeam
            ]

            # If we have a valid set of options choose from them
            if len(selection_pool) > 0:
                # let our current team know we won't be pointing to them anymore
                oldTeam = None
                if not self.isAtomic():
                    oldTeam = self.teamAction
                    self.teamAction.inLearners.remove(str(learner_id))

                self.teamAction = random.choice(selection_pool)
                # Let the new team know we're pointing to them
                self.teamAction.inLearners.append(str(learner_id))

                #if oldTeam != None:
                #    print("Learner {} switched from Team {} to Team {}".format(learner_id, oldTeam.id, self.teamAction.id))

        return self
Beispiel #21
0
    def bid(self, state):
        Program.execute(state, self.registers, self.program.modes,
                        self.program.operations, self.program.destinations,
                        self.program.sources)

        return self.registers[0]
Beispiel #22
0
class ConfLearner:

    """
    Create a new learner, either copied from the original or from a program or
    action. Either requires a learner, or a program/action pair.
    """
    def init_def(self, initParams, program, actionObj, numRegisters, learner_id=None):
        self.program = Program(
            instructions=program.instructions
        ) #Each learner should have their own copy of the program
        self.actionObj = ActionObject(action=actionObj, initParams=initParams) #Each learner should have their own copy of the action object
        self.registers = np.zeros(numRegisters, dtype=float)

        self.ancestor = None #By default no ancestor

        '''
        TODO What's self.states? 
        '''
        self.states = []


        self.inTeams = [] # Store a list of teams that reference this learner, incoming edges
        

        self.genCreate = initParams["generation"] # Store the generation that this learner was created on

        '''
        TODO should this be -1 before it sees any frames?
        '''
        self.frameNum = 0 # Last seen frame is 0

        # Assign id from initParams counter
        self.id = uuid.uuid4()


        if not self.isActionAtomic():
            self.actionObj.teamAction.inLearners.append(str(self.id))

        #print("Creating a brand new learner" if learner_id == None else "Creating a learner from {}".format(str(learner_id)))
        #print("Created learner {} [{}] -> {}".format(self.id, "atomic" if self.isActionAtomic() else "Team", self.actionObj.actionCode if self.isActionAtomic() else self.actionObj.teamAction.id))
        

    """
    Get the bid value, highest gets its action selected.
    """
    def bid_def(self, state, actVars=None):
        # exit early if we already got bidded this frame
        if self.frameNum == actVars["frameNum"]:
            return self.registers[0]

        self.frameNum = actVars["frameNum"]

        Program.execute(state, self.registers,
                        self.program.instructions[:,0], self.program.instructions[:,1],
                        self.program.instructions[:,2], self.program.instructions[:,3])

        return self.registers[0]

    """
    Get the bid value, highest gets its action selected. Passes memory args to program.
    """
    def bid_mem(self, state, actVars=None):
        # exit early if we already got bidded this frame
        if self.frameNum == actVars["frameNum"]:
            return self.registers[0]

        self.frameNum = actVars["frameNum"]

        Program.execute(state, self.registers,
                        self.program.instructions[:,0], self.program.instructions[:,1],
                        self.program.instructions[:,2], self.program.instructions[:,3],
                        actVars["memMatrix"], actVars["memMatrix"].shape[0], actVars["memMatrix"].shape[1],
                        Program.memWriteProbFunc)

        return self.registers[0]

    """
    Returns the action of this learner, either atomic, or requests the action
    from the action team.
    """
    def getAction_def(self, state, visited, actVars=None, path_trace=None):
        return self.actionObj.getAction(state, visited, actVars=actVars, path_trace=path_trace)



    """
    Gets the team that is the action of the learners action object.
    """
    def getActionTeam_def(self):
        return self.actionObj.teamAction

    """
    Returns true if the action is atomic, otherwise the action is a team.
    """
    def isActionAtomic_def(self):
        return self.actionObj.isAtomic()

    """
    Mutates either the program or the action or both.
    """
    def mutate_def(self, mutateParams, parentTeam, teams, pActAtom):

        changed = False
        while not changed:
            # mutate the program
            if flip(mutateParams["pProgMut"]):

                changed = True
              
                self.program.mutate(mutateParams)

            # mutate the action
            if flip(mutateParams["pActMut"]):

                changed = True
                
                self.actionObj.mutate(mutateParams, parentTeam, teams, pActAtom, learner_id=self.id)

        return self