コード例 #1
0
ファイル: agent.py プロジェクト: gomes717/SI_tarefas
class Agent:
    """"""
    counter = -1 # Contador de passos no plano, usado na deliberação

    def __init__(self, model):
        """Construtor do agente.
        @param model: Referência do ambiente onde o agente atuará."""
        self.model = model

        self.prob = Problem()
        # @TODO T_AAFP - criar crencas sobre as paredes do labirinto
        self.prob.createMaze(9, 9)
        self.prob.mazeBelief.putVerticalWall(0,1,0)
        self.prob.mazeBelief.putVerticalWall(0,0,1)
        self.prob.mazeBelief.putVerticalWall(5,8,1)
        self.prob.mazeBelief.putVerticalWall(5,5,2)
        self.prob.mazeBelief.putVerticalWall(8,8,2)

        self.prob.mazeBelief.putHorizontalWall(4,7,0)
        self.prob.mazeBelief.putHorizontalWall(7,7,1)
        self.prob.mazeBelief.putHorizontalWall(3,5,2)
        self.prob.mazeBelief.putHorizontalWall(3,5,3)
        self.prob.mazeBelief.putHorizontalWall(7,7,3)

        self.prob.mazeBelief.putVerticalWall(6,7,4)
        self.prob.mazeBelief.putVerticalWall(5,6,5)
        self.prob.mazeBelief.putVerticalWall(5,7,7)

        # Posiciona fisicamente o agente no estado inicial
        initial = self.positionSensor()
        self.prob.defInitialState(initial.row, initial.col)
        self.cost = 0
        self.nextState =  self.prob.initialState
        # Define o estado atual do agente = estado inicial
        self.currentState = self.prob.initialState
        # @TODO T_AAFP - defina estado objetivo
        # Define o estado objetivo
        # self.prob.defGoalState(?, ?)
        self.prob.defGoalState(0,8)
        # o metodo abaixo serve apenas para a view desenhar a pos objetivo
        # self.model.setGoalPos(2,8)
        self.model.setGoalPos(0,8)
        # Plano de busca - inicialmente vazio (equivale a solucao)
        self.plan = None


    def printPlan(self):
        """Apresenta o plano de busca."""
        print("--- PLANO ---")
        # @TODO: Implementação do aluno
        for plannedAction in self.plan:
            print("{} > ".format(action[plannedAction]),end='')
        print("FIM\n\n")

    def deliberate(self):
        # Primeira chamada, realiza busca para elaborar um plano
        # @TODO T_AAFP: Implementação do aluno
        if self.counter == -1:
            # @TODO T_AAFP: dar um plano fixo ao agente (preh-programado) - ver cardinal.py
            # @TODO T_AAFP: plano = solucao: contem acoes que levam o agente ateh o estado objetivo
            self.plan = [0,0,0,1,2,2,2,2,1,1,2,0,0]

            if self.plan != None:
                self.printPlan()
            else:
                print("SOLUÇÃO NÃO ENCONTRADA")
                return -1

        # Nas demais chamadas, executa o plano já calculado
        self.counter += 1

        # @TODO T_AAFP - testar se atingiu o estado objetivo ou se chegou ao final do plano sem alcancar o objetivo
        if(self.prob.goalTest(self.positionSensor())):
            #colocar print final aqui
            print("*************** ultimo ciclo ***********************")
            print("estado atual:" + str(self.currentState))
            print("ct = "+ str(self.counter) +" de "+str(len(self.plan)))
            print("custo ate o momento (com a acao escolhida):"+str(self.cost))
            print("Objetivo conquistado!!!")
            print("****************************************************\n")
            return -1
        elif(self.counter == len(self.plan)):
                #colocar um print aqui depois
            print("*************** ultimo ciclo ***********************")
            print("estado atual:" + str(self.currentState))
            print("ct = "+ str(self.counter) +" de "+str(len(self.plan)))
            print("custo ate o momento (com a acao escolhida):"+str(self.cost))
            print("Objetivo nao conquistado!!")
            print("****************************************************\n")
            return -1


        possibleAction = self.prob.possibleActions(self.positionSensor())
        currentAction = self.plan[self.counter]
        self.nextState = self.prob.suc(self.currentState,currentAction)
        # @TODO T_AAFP - fazer prints solicitados
        print("*************** inicio do ciclo ***********************")
        print("estado atual:" + str(self.currentState))
        print("proximo estado:" + str(self.nextState))
        print("açoes possiveis:{ ", end= '')
        for i in range(len(action)):
            if(possibleAction[i]==1):
                print("{} ".format(action[i]),end='')
        print("}")
        print("ct = "+ str(self.counter) +" de "+str(len(self.plan))+  ". Ação escolhida=" +action[currentAction])
        print("custo ate o momento (com a acao escolhida):" + str(self.cost))
        print("****************************************************\n")
        # @TODO T_AAFP - o agente deve executar a acao e atualizar seu estado atual


        self.executeGo(currentAction)
        self.cost += self.prob.getActionCost(currentAction)
        self.currentState = self.positionSensor()
        return 1

    def executeGo(self, direction):
        """Atuador: solicita ao agente física para executar a ação.
        @param direction: Direção da ação do agente
        @return 1 caso movimentação tenha sido executada corretamente."""
        self.model.go(direction)
        return 1

    def positionSensor(self):
        """Simula um sensor que realiza a leitura do posição atual no ambiente e traduz para uma instância da classe Estado.
        @return estado que representa a posição atual do agente no labirinto."""
        pos = self.model.agentPos
        return State(pos[0],pos[1])
コード例 #2
0
ファイル: agent.py プロジェクト: peteco-utfpr/Projeto-RoboFun
class Agent:
    def __init__(self, model):
        """Construtor do agente.
        @param model: Referência do ambiente onde o agente atuará."""
        self.model = model

        ## Pega o tipo de mesh, que está no model (influência na movimentação)
        self.mesh = self.model.mesh


        ## Cria a instância do problema para o agente
        self.prob = Problem()
        self.prob.createMaze(model.rows, model.columns, model.maze)
    
        
        # Posiciona fisicamente o agente no estado inicial
        initial = self.positionSensor()
        self.prob.defInitialState(initial.row, initial.col)
        
        # Define o estado atual do agente = estado inicial
        self.currentState = self.prob.initialState

        # Define o estado objetivo
        self.prob.defGoalState(model.goalPos[0], model.goalPos[1])


        """
        DEFINE OS PLANOS DE EXECUÇÃO DO AGENTE
        """
        ##Para usar o Planner online, exemplo abaixo:
        ##plann = Planner()
        ##print(plann.generate())

        
        # Plano de busca - inicialmente vazio (equivale a solucao)
        self.plan = []
        ##Custo da solução
        self.costAll = 0

        ## Cria a instancia do algoritmo LRTA*
        self.planToGoal = Lrta(model.rows, model.columns, self.prob.goalState, initial, "goal", self.mesh)
        self.planToGoal.startManhattanHeuristic(self.prob.mazeBelief.walls)  
        
        ## Coloca na biblioteca de planos todos os planos possíveis
        self.libPlan = [] 

        ## Coloca dentro do plano as ações, nesse caso, ele deve executar o LRTA
        self.plan = []


    ## Metodo que define a deliberacao do agente 
    def deliberate(self):
        ## Verifica se há algum plano a ser executado
        if len(self.plan) == 0:
            return -1
        print ("******************************Inicio do ciclo***************")
        print("Posição agente  : {0},{1}".format(self.model.agentPos[0],self.model.agentPos[1]))

        ## Define a proxima acao a ser realizada como a primeira do plano
        currentAction = self.plan[0]
        ## Executa esse acao, atraves do metodo executeGo 
        self.executeGo(currentAction)
        ## Redefine o estado atual do agente
        self.currentState = self.positionSensor()
        ## Atualiza a biblioteca de planos
        self.updateLibPlan()

        ## Soma o custo da acao com o total 
        self.costAll += self.prob.getActionCost(currentAction)
        print ("Custo até o momento (com a ação escolhida):", self.costAll) 
        print ("***************************************************************")
        return 1

    ## Metodo que executa as acoes
    def executeGo(self, action):
        """Atuador: solicita ao agente físico para executar a acao.
        @param direction: Direcao da acao do agente
        @return 1 caso movimentacao tenha sido executada corretamente."""
        ## Passa a acao para o modelo
        result = self.model.go(action)
        ## Se o resultado for True, significa que a acao foi completada com sucesso, e ja pode ser removida do plano
        if (result):
            del self.plan[0]
            self.actionGo([6,7], True)
        return 1

    ## Metodo que pega a posicao real do agente no ambiente
    def positionSensor(self):
        """Simula um sensor que realiza a leitura do posição atual no ambiente e traduz para uma instância da classe Estado.
        @return estado que representa a posição atual do agente no labirinto."""
        pos = self.model.agentPos
        return State(pos[0],pos[1])

    ## Metodo que atualiza a biblioteca de planos, de acordo com o estado atual do agente
    def updateLibPlan(self):
        for i in self.libPlan:
            i.updateCurrentState(self.currentState)

    def actionGo(self, posAction, action = True):
        self.model.do(posAction, action)

    def addPlan(self, plano):
        self.plan.append(plano)
コード例 #3
0
class Agent:
    """"""
    counter = -1  # Contador de passos no plano, usado na deliberação

    def __init__(self, model):
        """Construtor do agente.
        @param model: Referência do ambiente onde o agente atuará."""
        self.model = model

        self.prob = Problem()
        self.prob.createMaze(6, 6)
        self.prob.mazeBelief.putVerticalWall(2, 4, 3)
        self.prob.mazeBelief.putHorizontalWall(0, 1, 2)
        self.prob.mazeBelief.putBox(4, 1)
        self.prob.mazeBelief.putBox(4, 2)
        self.prob.mazeBelief.putBox(3, 4)
        self.prob.mazeBelief.putBox(1, 3)

        # Posiciona fisicamente o agente no estado inicial
        initial = self.positionSensor()
        self.prob.defInitialState(initial.row, initial.col)

        # Define o estado atual do agente = estado inicial
        self.currentState = self.prob.initialState

        # Plano de busca
        self.plan = None

    def printPlan(self):
        """Apresenta o plano de busca."""
        print("--- PLANO ---")
        # @TODO: Implementação do aluno
        for plannedAction in self.plan:
            print("{} > ".format(action[plannedAction]), end='')
        print("FIM\n\n")

    def deliberate(self):
        # Primeira chamada, realiza busca para elaborar um plano
        # @TODO: Implementação do aluno
        if self.counter == -1:
            self.plan = self.cheapestFirstSearch(
                1
            )  # 0 = custo uniforme, 1 = A* com colunas, 2 = A* com dist Euclidiana
            if self.plan != None:
                self.printPlan()
            else:
                print("SOLUÇÃO NÃO ENCONTRADA")
                return -1

        # Nas demais chamadas, executa o plano já calculado
        self.counter += 1

        # Atingiu o estado objetivo
        if self.prob.goalFinalTest():
            print("!!! ATINGIU O ESTADO OBJETIVO !!!")
            return -1
        # Algo deu errado, chegou ao final do plano sem atingir o objetivo
        if self.counter >= len(self.plan):
            print(
                "### ERRO: plano chegou ao fim, mas objetivo não foi atingido."
            )
            return -1
        currentAction = self.plan[self.counter]

        print("--- Mente do Agente ---")
        print("{0:<20}{1}".format("Estado atual :", self.currentState))
        print("{0:<20}{1} de {2}. Ação= {3}\n".format("Passo do plano :",
                                                      self.counter + 1,
                                                      len(self.plan),
                                                      action[currentAction]))
        self.executeGo(currentAction)

        # Atualiza o estado atual baseando-se apenas nas suas crenças e na função sucessora
        # Não faz leitura do sensor de posição
        self.currentState = self.prob.suc(self.currentState, currentAction)
        return 1

    def executeGo(self, direction):
        """Atuador: solicita ao agente física para executar a ação.
        @param direction: Direção da ação do agente
        @return 1 caso movimentação tenha sido executada corretamente."""
        self.model.go(direction)
        return 1

    def positionSensor(self):
        """Simula um sensor que realiza a leitura do posição atual no ambiente e traduz para uma instância da classe Estado.
        @return estado que representa a posição atual do agente no labirinto."""
        pos = self.model.agentPos
        return State(pos[0], pos[1])

    def hn1(self, state, action):
        """Implementa uma heurísitca - número 1 - para a estratégia A*.
        No caso hn1 é a distância em linhas do estado passado com argumento até a linhas do estado objetivo.
        @param state: estado para o qual se quer calcular o valor de h(n)."""
        distance = 0
        distRow = 0
        distCol = 0
        distColGoal = 0
        for row in range(self.prob.mazeBelief.maxRows - 1):
            for col in range(self.prob.mazeBelief.maxColumns):
                if self.prob.mazeBelief.walls[row][col] == 2:
                    pushesBox = 8
                    # IFs para compracao ao redor da caixa e ver algum cenario de deadlock
                    # consequentemente vejo todas as posicoes ao redor da caixa e
                    # se a caixa ossui algum obstaculo para movela
                    # se possuir subo o numero de pushesBoes para um numero bem alto
                    # se os movimentos forem livres seto o numero de pushes baseado numa matrix 3 por 3
                    # e na distancia de manhattan

                    # Checo se tenho a matrix 3 por 3 em volta da box
                    if (state.col == col - 1 or state.col == col or state.col
                            == col + 1) and (state.row == row - 1 or state.row
                                             == row or state.row == row + 1):
                        pushesBox = 4
                        # vejo se os limites estao dentro da matrix
                        if row - 1 > 0 and col - 1 > 0 and row + 1 < self.prob.maxRows and col + 1 < self.prob.maxColumns:
                            if state.col == col - 1 and state.row == row - 1:  # posicao 0,0 na matriz emvolta da Box
                                pushesBox = 2
                            if state.col == col and state.row == row - 1:  # posicao 0,1 na matriz emvolta da Box
                                pushesBox = 1
                            if state.col == col + 1 and state.row == row - 1:  # posicao 0,2 na matriz emvolta da Box
                                pushesBox = 2
                            if state.col == col - 1 and state.row == row:  # posicao 1,0 na matriz emvolta da Box
                                pushesBox = 1
                            if state.col == col and state.row == row:  # posicao 1,1 na matriz emvolta da Box
                                pushesBox = 0
                            if state.col == col + 1 and state.row == row:  # posicao 1,2 na matriz emvolta da Box
                                pushesBox = 1
                            if state.col == col - 1 and state.row == row + 1:  # posicao 2,1 na matriz emvolta da Box
                                pushesBox = 2
                            if state.col == col and state.row == row + 1:  # posicao 2,2 na matriz emvolta da Box
                                pushesBox = 1
                            if state.col == col + 1 and state.row == row + 1:  # posicao 2,3 na matriz emvolta da Box
                                pushesBox = 2
                        # se nao estiverem testo para deadlock
                        # else:
                    else:
                        # pushesBox = 4
                        #pushesBox = # deixo menos pesado para i para cima do q para baixo pois nas colunas limites
                        # a caixa so pode so deve se movimentar para baixo
                        # else:
                        pushesBox = 16
                        # colunas sendo o limite de 0 ou 5 posso testar o movimento para baixo

                    distRow = abs(
                        row -
                        5)  # calculo individual da caixa para a linha obj
                    if self.prob.mazeBelief.walls[5][col] == 2:
                        # loop para ver qual objetivo esta mais perto e vazio
                        for colGoal in range(self.prob.mazeBelief.maxColumns):
                            distColGoal = 5
                            if self.prob.mazeBelief.walls[5][colGoal] != 2:
                                distColGoal = abs(col - colGoal)
                                if distColGoal < distCol:
                                    distCol = distCol + distColGoal
                    else:
                        distCol = 0

                    distance = distance + distRow + distCol + pushesBox

        return distance

    def hn2(self, state):
        """Implementa uma heurísitca - número 2 - para a estratégia A*.
        No caso hn1 é a distância distância euclidiana do estado passado com argumento até o estado objetivo.
        @param state: estado para o qual se quer calcular o valor de h(n)."""
        # @TODO: Implementação do aluno
        distCol = abs(state.col - self.prob.goalState.col)
        distRow = abs(state.row - self.prob.goalState.row)
        squared = distRow**2 + distCol**2
        return squared**0.5

    def cheapestFirstSearch(self, searchType):
        """Realiza busca com a estratégia de custo uniforme ou A* conforme escolha realizada na chamada.
        @param searchType: 0=custo uniforme, 1=A* com heurística hn1; 2=A* com hn2
        @return plano encontrado"""
        # @TODO: Implementação do aluno
        # Atributos para análise de desempenho
        treeNodesCt = 0  # contador de nós gerados incluídos na árvore
        # nós inseridos na árvore, mas que não necessitariam porque o estado
        # já foi explorado ou por já estar na fronteira
        exploredDicardedNodesCt = 0
        frontierDiscardedNodesCt = 0

        # Algoritmo de busca
        solution = None
        solutionBox = []
        root = TreeNode(parent=None)
        root.state = self.prob.initialState
        root.gn = 0
        root.hn = 0
        root.action = -1
        treeNodesCt += 1

        # cria FRONTEIRA com estado inicial
        frontier = []
        frontier.append(root)

        # cria EXPLORADOS - inicialmente vazia
        explored = []

        print("\n*****\n***** INICIALIZAÇÃO ÁRVORE DE BUSCA\n*****\n")
        print("\n{0:<30}{1}".format("Nós na árvore: ", treeNodesCt))
        print("{0:<30}{1}".format("Descartados já na fronteira: ",
                                  frontierDiscardedNodesCt))
        print("{0:<30}{1}".format("Descartados já explorados: ",
                                  exploredDicardedNodesCt))
        print("{0:<30}{1}".format(
            "Total de nós gerados: ",
            treeNodesCt + frontierDiscardedNodesCt + exploredDicardedNodesCt))

        while len(frontier):  # Fronteira não vazia
            print("\n*****\n***** Início iteração\n*****\n")
            printFrontier(frontier)

            selNode = frontier.pop(0)  # retira nó da fronteira
            selState = selNode.state
            print("Selecionado para expansão: {}\n".format(selNode))

            if self.prob.goalBoxTest():
                solutionBox.append(selNode)
                if self.prob.goalFinalTest():
                    solution = selNode
                    break
            explored.append(selNode)
            printExplored(explored)

            # Obtem ações possíveis para o estado selecionado para expansão
            actions = self.prob.possibleActionsWithoutCollaterals(
                selState)  # actions é do tipo [-1, -1, -1, 1, 1, -1, -1, -1]

            for actionIndex, act in enumerate(actions):
                if (act < 0):  # Ação não é possível
                    continue

                # INSERE NÓ FILHO NA ÁRVORE DE BUSCA - SEMPRE INSERE, DEPOIS
                # VERIFICA SE O INCLUI NA FRONTEIRA OU NÃO
                # Instancia o filho ligando-o ao nó selecionado (nSel)
                child = selNode.addChild()
                # Obtem o estado sucessor pela execução da ação <act>
                sucState = self.prob.suc(selState, actionIndex)
                child.state = sucState
                # Custo g(n): custo acumulado da raiz até o nó filho
                gnChild = selNode.gn + self.prob.getActionCost(actionIndex)
                if searchType == UNIFORME_COST:
                    child.setGnHn(
                        gnChild, 0
                    )  # Deixa h(n) zerada porque é busca de custo uniforme
                elif searchType == A_START_1:
                    child.setGnHn(gnChild, self.hn1(sucState, actionIndex))
                elif searchType == A_START_2:
                    child.setGnHn(gnChild, self.hn2(sucState))

                child.action = actionIndex
                # INSERE NÓ FILHO NA FRONTEIRA (SE SATISFAZ CONDIÇÕES)

                # Testa se estado do nó filho foi explorado
                alreadyExplored = False
                # for node in explored:
                #     if child.state == node.state:
                #         alreadyExplored = True
                #         break

                # Testa se estado do nó filho está na fronteira, caso esteja
                # guarda o nó existente em nFront
                nodeFront = None
                if not alreadyExplored:
                    for node in frontier:
                        if (child.state == node.state):
                            nodeFront = node
                            break
                # Se ainda não foi explorado
                if not alreadyExplored:
                    # e não está na fronteira, adiciona à fronteira
                    if nodeFront == None:
                        frontier.append(child)
                        frontier.sort(key=lambda x: x.getFn(
                        ))  # Ordena a fronteira pelo f(n), ascendente
                        treeNodesCt += 1
                    else:
                        # Se já está na fronteira temos que ver se é melhor
                        if nodeFront.getFn() > child.getFn(
                        ):  # Nó da fronteira tem custo maior que o filho
                            frontier.remove(
                                nodeFront
                            )  # Remove nó da fronteira (pior e deve ser substituído)
                            nodeFront.remove()  # Retira-se da árvore
                            frontier.append(
                                child)  # Adiciona filho que é melhor
                            frontier.sort(key=lambda x: x.getFn(
                            ))  # Ordena a fronteira pelo f(n), ascendente
                            # treeNodesCt não é incrementado por inclui o melhor e retira o pior
                        else:
                            # Conta como descartado porque o filho é pior que o nó da fronteira e foi descartado
                            frontierDiscardedNodesCt += 1
                else:
                    exploredDicardedNodesCt += 1

            print("\n{0:<30}{1}".format("Nós na árvore: ", treeNodesCt))
            print("{0:<30}{1}".format("Descartados já na fronteira: ",
                                      frontierDiscardedNodesCt))
            print("{0:<30}{1}".format("Descartados já explorados: ",
                                      exploredDicardedNodesCt))
            print("{0:<30}{1}".format(
                "Total de nós gerados: ", treeNodesCt +
                frontierDiscardedNodesCt + exploredDicardedNodesCt))

        if (solution != None):
            print("!!! Solução encontrada !!!")
            print("!!! Custo:        {}".format(solution.gn))
            print("!!! Profundidade: {}\n".format(solution.depth))
            print("\n{0:<30}{1}".format("Nós na árvore: ", treeNodesCt))
            print("{0:<30}{1}".format("Descartados já na fronteira: ",
                                      frontierDiscardedNodesCt))
            print("{0:<30}{1}".format("Descartados já explorados: ",
                                      exploredDicardedNodesCt))
            print("{0:<30}{1}".format(
                "Total de nós gerados: ", treeNodesCt +
                frontierDiscardedNodesCt + exploredDicardedNodesCt))
            return buildPlan(solution)
        else:
            print("### Solução NÃO encontrada ###")
            return None
コード例 #4
0
class Agent:
    """"""
    counter = -1  # Contador de passos no plano, usado na deliberação

    def __init__(self, model):
        """Construtor do agente.
        @param model: Referência do ambiente onde o agente atuará."""
        self.model = model

        self.prob = Problem()
        self.prob.createMaze(6, 6)

        self.prob.mazeBelief.putVerticalWall(2, 4, 3)
        self.prob.mazeBelief.putHorizontalWall(0, 1, 2)

        # Posiciona fisicamente o agente no estado inicial
        initial = self.positionSensor()
        self.prob.defInitialState(initial.row, initial.col, initial.boxes)

        # Define o estado atual do agente = estado inicial
        self.currentState = self.prob.initialState

        # Define o estado objetivo
        self.prob.defGoalState(0, 0, [(5, 1), (5, 4), (5, 5)])
        self.model.addGoalPos(5, 5)
        self.model.addGoalPos(5, 4)
        #self.model.addGoalPos(5,3)
        #self.model.addGoalPos(5,2)
        self.model.addGoalPos(5, 1)
        #self.model.addGoalPos(5,0)

        # Plano de busca
        self.plan = None

    def deliberate(self):
        # Primeira chamada, realiza busca para elaborar um plano
        if self.counter == -1:
            self.plan = self.cheapestFirstSearch(
                H_OPT
            )  # 0 = custo uniforme, 1 = A* com colunas, 2 = A* com dist Euclidiana
            if self.plan != None:
                self.printPlan()
            else:
                print("SOLUÇÃO NÃO ENCONTRADA")
                return -1

        # Nas demais chamadas, executa o plano já calculado
        self.counter += 1

        # Atingiu o estado objetivo
        if self.prob.goalTest(self.currentState):
            print("!!! ATINGIU O ESTADO OBJETIVO !!!")
            return -1
        # Algo deu errado, chegou ao final do plano sem atingir o objetivo
        if self.counter >= len(self.plan):
            print(
                "### ERRO: plano chegou ao fim, mas objetivo não foi atingido."
            )
            return -1
        currentAction = self.plan[self.counter]

        print("--- Mente do Agente ---")
        print("{0:<20}{1}".format("Estado atual :", self.currentState))
        print("{0:<20}{1} de {2}. Ação= {3}\n".format("Passo do plano :",
                                                      self.counter + 1,
                                                      len(self.plan),
                                                      action[currentAction]))
        self.executeGo(currentAction)

        # Atualiza o estado atual baseando-se apenas nas suas crenças e na função sucessora
        # Não faz leitura do sensor de posição
        self.currentState = self.prob.suc(self.currentState, currentAction)
        return 1

    def executeGo(self, direction):
        """Atuador: solicita ao agente física para executar a ação.
        @param direction: Direção da ação do agente
        @return 1 caso movimentação tenha sido executada corretamente."""
        self.model.go(direction)
        return 1

    def positionSensor(self):
        """Simula um sensor que realiza a leitura do posição atual no ambiente e traduz para uma instância da classe Estado.
        @return estado que representa a posição atual do agente no labirinto."""
        pos = self.model.agentPos
        return State(pos[0], pos[1], self.model.boxPos, 0)

    def hn(self, state):
        goalBoxes = self.prob.goalState.boxes
        h = 0
        distsToAgent = []
        for i in range(len(goalBoxes)):
            box = goalBoxes[i]
            sBox = state.boxes[i]
            distsToAgent.append(
                (abs(sBox[0] - state.row), abs(sBox[1] - state.col)))
            h += abs(box[0] - sBox[0]) + abs(box[1] - sBox[1])

        minDist = min(distsToAgent)
        h += minDist[0] + minDist[
            1]  # menor distancia entre o agente e as caixas
        return h

    def hnmeans(self, state):
        goalBoxes = self.prob.goalState.boxes
        h = 0
        for gbox in goalBoxes:
            m = 0
            for sbox in state.boxes:
                m += abs(gbox[0] - sbox[0]) + abs(gbox[1] - sbox[1])
            h += (m / len(state.boxes)) + (abs(sbox[0] - state.row) +
                                           abs(sbox[1] - state.col))
        return h

    def hnwall(self, state):
        goalBoxes = self.prob.goalState.boxes
        h = 0
        distsToAgent = []
        for i in range(len(goalBoxes)):
            box = goalBoxes[i]
            sBox = state.boxes[i]
            distsToAgent.append(
                abs(sBox[0] - state.row) + abs(sBox[1] - state.col) +
                self.prob.checkWall(sBox, (state.row, state.col)))
            h += abs(box[0] - sBox[0]) + abs(box[1] -
                                             sBox[1]) + self.prob.checkWall(
                                                 sBox, box)

        minDist = min(distsToAgent)
        h += minDist  # menor distancia entre o agente e as caixas
        return h

    def hnOptm(self, state):
        distsg = [(state.row, state.col)]
        distsg += [box for box in self.prob.goalState.boxes]
        dists = [box for box in state.boxes]
        distsg.sort()
        dists.sort()
        h = 0
        for i in range(len(dists)):
            h += abs(dists[i][0] - distsg[i][0]) + abs(dists[i][1] -
                                                       distsg[i][1])
            h += abs(dists[i][0] - distsg[i + 1][0]) + abs(dists[i][1] -
                                                           distsg[i + 1][1])
        return h

    def hnOptmWall(self, state):
        distsg = [(state.row, state.col)]
        distsg += [box for box in self.prob.goalState.boxes]
        dists = [box for box in state.boxes]
        distsg.sort()
        dists.sort()
        h = 0
        for i in range(len(dists)):
            h += abs(dists[i][0] - distsg[i][0]) + abs(dists[i][1] -
                                                       distsg[i][1])
            h += abs(dists[i][0] - distsg[i + 1][0]) + abs(dists[i][1] -
                                                           distsg[i + 1][1])
            h += self.prob.checkWall(dists[i],
                                     distsg[i]) + self.prob.checkWall(
                                         dists[i], distsg[i + 1])
        return h

    def hnOptmEucl(self, state):
        distsg = [(state.row, state.col)]
        distsg += [box for box in self.prob.goalState.boxes]
        dists = [box for box in state.boxes]
        distsg.sort()
        dists.sort()
        h = 0
        for i in range(len(dists)):
            h += abs(dists[i][0] - distsg[i][0])**2
            h += abs(dists[i][1] - distsg[i][1])**2
            h += abs(dists[i][0] - distsg[i + 1][0])**2
            h += abs(dists[i][1] - distsg[i + 1][1])**2
        return h**0.5

    def cheapestFirstSearch(self, searchType):
        """Realiza busca com a estratégia de custo uniforme ou A* conforme escolha realizada na chamada.
        @param searchType: 0=custo uniforme, 1=A* com heurística hn1; 2=A* com hn2
        @return plano encontrado"""
        # Atributos para análise de desempenho
        treeNodesCt = 0  # contador de nós gerados incluídos na árvore
        # nós inseridos na árvore, mas que não necessitariam porque o estado
        # já foi explorado ou por já estar na fronteira
        exploredDicardedNodesCt = 0
        frontierDiscardedNodesCt = 0

        # Algoritmo de busca
        solution = None
        root = TreeNode(parent=None)
        root.state = self.prob.initialState
        root.gn = 0
        root.hn = 0
        root.action = -1
        treeNodesCt += 1

        # cria FRONTEIRA com estado inicial
        frontier = []
        frontier.append(root)

        # cria EXPLORADOS - inicialmente vazia
        explored = {}

        print("\n*****\n***** INICIALIZAÇÃO ÁRVORE DE BUSCA\n*****\n")
        print("\n{0:<30}{1}".format("Nós na árvore: ", treeNodesCt))
        print("{0:<30}{1}".format("Descartados já na fronteira: ",
                                  frontierDiscardedNodesCt))
        print("{0:<30}{1}".format("Descartados já explorados: ",
                                  exploredDicardedNodesCt))
        print("{0:<30}{1}".format(
            "Total de nós gerados: ",
            treeNodesCt + frontierDiscardedNodesCt + exploredDicardedNodesCt))

        while len(frontier):  # Fronteira não vazia
            print("\n*****\n***** Início iteração\n*****\n")
            #printFrontier(frontier)

            selNode = frontier.pop(0)  # retira nó da fronteira
            selState = selNode.state
            print("Selecionado para expansão: {}\n".format(selNode))

            # Teste de objetivo
            if selState == self.prob.goalState:
                solution = selNode
                break
            explored[str(selState.row) + str(selState.col) +
                     str(selState.boxes)] = selState
            #printExplored(explored)

            # Obtem ações possíveis para o estado selecionado para expansão
            actions = self.prob.possibleActions(
                selState)  # actions é do tipo [-1, -1, -1, 1 ]
            if selNode.gn >= LIMITE_BUSCA and VERIFICA_LIMITE:
                continue

            for actionIndex, act in enumerate(actions):
                if (act < 0):  # Ação não é possível
                    continue

                # INSERE NÓ FILHO NA ÁRVORE DE BUSCA - SEMPRE INSERE, DEPOIS
                # VERIFICA SE O INCLUI NA FRONTEIRA OU NÃO
                # Obtem o estado sucessor pela execução da ação <act>
                sucState = self.prob.suc(selState, actionIndex)

                # verifica se a acao sucessora bloqueia o tabuleiro
                if (VERIFICA_ACAO_BLOQUEIO
                        and self.prob.isBlockAction(sucState)):
                    continue

                # Instancia o filho ligando-o ao nó selecionado (nSel)
                child = selNode.addChild()
                child.state = sucState

                # Custo g(n): custo acumulado da raiz até o nó filho
                gnChild = selNode.gn + self.prob.getActionCost(actionIndex)

                if searchType == UNIFORME_COST:
                    child.setGnHn(
                        gnChild, 0
                    )  # Deixa h(n) zerada porque é busca de custo uniforme

                elif searchType == HEURISTICA_DISTS:
                    child.setGnHn(gnChild, self.hn(sucState))

                elif searchType == HEURISTICA_DISTS_PEN_OBSTACULOS:
                    child.setGnHn(gnChild, self.hnwall(sucState))

                elif searchType == H_OPT:
                    child.setGnHn(gnChild, self.hnOptm(sucState))

                elif searchType == H_EUCL:
                    child.setGnHn(gnChild, self.hnOptmEucl(sucState))

                elif searchType == H_OPT_PEN:
                    child.setGnHn(gnChild, self.hnOptmWall(sucState))
                child.action = actionIndex
                # INSERE NÓ FILHO NA FRONTEIRA (SE SATISFAZ CONDIÇÕES)
                alreadyExplored = False

                # Testa se estado do nó filho foi explorado
                expHash = str(child.state.row) + str(child.state.col) + str(
                    child.state.boxes)
                if expHash in explored:
                    exp = explored[expHash]
                    if (child.state.cost >= exp.cost):
                        alreadyExplored = True

                # Testa se estado do nó filho está na fronteira, caso esteja
                # guarda o nó existente em nFront
                nodeFront = None
                if not alreadyExplored:
                    for node in frontier:
                        if (child.state == node.state
                                and child.state.row == node.state.row
                                and child.state.col == node.state.col):
                            nodeFront = node
                            break
                # Se ainda não foi explorado
                if not alreadyExplored:
                    # e não está na fronteira, adiciona à fronteira
                    if nodeFront == None:
                        # adiciona na fronteira se a acao nao bloqueia a solucao
                        frontier.append(child)
                        frontier.sort(
                            key=lambda x: (x.getFn(), x.hn)
                        )  # Ordena a fronteira pelo f(n), usando o valor de hn como desempate
                        treeNodesCt += 1

                    else:
                        # Se já está na fronteira temos que ver se é melhor
                        if nodeFront.getFn() > child.getFn(
                        ):  # Nó da fronteira tem custo maior que o filho
                            frontier.remove(
                                nodeFront
                            )  # Remove nó da fronteira (pior e deve ser substituído)
                            nodeFront.remove()  # Retira-se da árvore
                            frontier.append(
                                child)  # Adiciona filho que é melhor
                            #frontier.sort(key=lambda x: x.getFn() )  # Ordena a fronteira pelo f(n), ascendente
                            frontier.sort(
                                key=lambda x: (x.getFn(), x.hn)
                            )  # Ordena a fronteira pelo f(n), usando o valor de hn como desempate
                            # treeNodesCt não é incrementado por inclui o melhor e retira o pior
                        else:
                            # Conta como descartado porque o filho é pior que o nó da fronteira e foi descartado
                            frontierDiscardedNodesCt += 1
                else:
                    exploredDicardedNodesCt += 1

            print("\n{0:<30}{1}".format("Nós na árvore: ", treeNodesCt))
            print("{0:<30}{1}".format("Descartados já na fronteira: ",
                                      frontierDiscardedNodesCt))
            print("{0:<30}{1}".format("Descartados já explorados: ",
                                      exploredDicardedNodesCt))
            print("{0:<30}{1}".format(
                "Total de nós gerados: ", treeNodesCt +
                frontierDiscardedNodesCt + exploredDicardedNodesCt))

        if (solution != None):
            print("!!! Solução encontrada !!!")
            print("!!! Custo:        {}".format(solution.gn))
            print("!!! Profundidade: {}\n".format(solution.depth))
            print("\n{0:<30}{1}".format("Nós na árvore: ", treeNodesCt))
            print("{0:<30}{1}".format("Descartados já na fronteira: ",
                                      frontierDiscardedNodesCt))
            print("{0:<30}{1}".format("Descartados já explorados: ",
                                      exploredDicardedNodesCt))
            print("{0:<30}{1}".format(
                "Total de nós gerados: ", treeNodesCt +
                frontierDiscardedNodesCt + exploredDicardedNodesCt))
            return buildPlan(solution)
        else:
            print("### Solução NÃO encontrada ###")
            return None

    def printPlan(self):
        """Apresenta o plano de busca."""
        print("--- PLANO ---")
        # @TODO: Implementação do aluno
        for plannedAction in self.plan:
            print("{} > ".format(action[plannedAction]), end='')
        print("FIM\n\n")
コード例 #5
0
ファイル: agent.py プロジェクト: MarcosGraebin/Labirinto
class Agent:
    """"""
    counter = -1 # Contador de passos no plano, usado na deliberação

    def __init__(self, model):
        """Construtor do agente.
        @param model: Referência do ambiente onde o agente atuará."""
        self.model = model

        self.prob = Problem()
        # @TODO T_AAFP - criar crencas sobre as pareded do labirinto
        self.prob.createMaze(9, 9)
        self.prob.mazeBelief.putVerticalWall(0,1,0)
        # ...


        # Posiciona fisicamente o agente no estado inicial
        initial = self.positionSensor()
        self.prob.defInitialState(initial.row, initial.col)
        
        # Define o estado atual do agente = estado inicial
        self.currentState = self.prob.initialState

        # @TODO T_AAFP - defina estado objetivo
        # Define o estado objetivo
        # self.prob.defGoalState(?, ?)

        # o metodo abaixo serve apenas para a view desenhar a pos objetivo
        # self.model.setGoalPos(2,8)

        # Plano de busca - inicialmente vazio (equivale a solucao)
        self.plan = None


    def printPlan(self):
        """Apresenta o plano de busca."""    
        print("--- PLANO ---")
        # @TODO: Implementação do aluno
        for plannedAction in self.plan:
            print("{} > ".format(action[plannedAction]),end='')
        print("FIM\n\n")

    def deliberate(self):
        # Primeira chamada, realiza busca para elaborar um plano
        # @TODO T_AAFP: Implementação do aluno
        if self.counter == -1: 
            # @TODO T_AAFP: dar um plano fixo ao agente (preh-programado) - ver cardinal.py
            # @TODO T_AAFP: plano = solucao: contem acoes que levam o agente ateh o estado objetivo
            # self.plan = []
            if self.plan != None:
                self.printPlan()
            else:
                print("SOLUÇÃO NÃO ENCONTRADA")
                return -1

        # Nas demais chamadas, executa o plano já calculado
        self.counter += 1

        # @TODO T_AAFP - testar se atingiu o estado objetivo ou se chegou ao final do plano sem alcancar o objetivo


        currentAction = self.plan[self.counter]

        # @TODO T_AAFP - fazer prints solicitados


        # @TODO T_AAFP - o agente deve executar a acao e atualizar seu estado atual


        return 1

    def executeGo(self, direction):
        """Atuador: solicita ao agente física para executar a ação.
        @param direction: Direção da ação do agente
        @return 1 caso movimentação tenha sido executada corretamente."""
        self.model.go(direction)
        return 1

    def positionSensor(self):
        """Simula um sensor que realiza a leitura do posição atual no ambiente e traduz para uma instância da classe Estado.
        @return estado que representa a posição atual do agente no labirinto."""
        pos = self.model.agentPos
        return State(pos[0],pos[1])
コード例 #6
0
class Agent:
    """"""
    counter = -1  # Contador de passos no plano, usado na deliberação

    def __init__(self, model):
        """Construtor do agente.
        @param model: Referência do ambiente onde o agente atuará."""
        self.model = model

        self.prob = Problem()

        self.prob.createMaze(9, 9)

        self.prob.mazeBelief.putVerticalWall(0, 1, 0)
        self.prob.mazeBelief.putVerticalWall(0, 0, 1)
        self.prob.mazeBelief.putHorizontalWall(4, 6, 0)
        self.prob.mazeBelief.putVerticalWall(0, 1, 7)
        self.prob.mazeBelief.putHorizontalWall(3, 5, 2)
        self.prob.mazeBelief.putHorizontalWall(3, 5, 3)
        self.prob.mazeBelief.putHorizontalWall(7, 7, 3)
        self.prob.mazeBelief.putHorizontalWall(1, 2, 5)
        self.prob.mazeBelief.putVerticalWall(6, 7, 1)
        self.prob.mazeBelief.putVerticalWall(6, 7, 4)
        self.prob.mazeBelief.putVerticalWall(5, 6, 5)
        self.prob.mazeBelief.putVerticalWall(5, 7, 7)
        self.prob.mazeBelief.putHorizontalWall(1, 2, 8)

        # Posiciona fisicamente o agente no estado inicial
        initial = self.positionSensor()
        self.prob.defInitialState(initial.row, initial.col)

        # Define o estado atual do agente = estado inicial
        self.currentState = self.prob.initialState

        # Define o estado objetivo
        self.prob.defGoalState(2, 8)

        # o metodo abaixo serve apenas para a view desenhar a pos objetivo
        self.model.setGoalPos(2, 8)

        # Plano de busca - inicialmente vazio (equivale a solucao)
        self.plan = None

    def printPlan(self):
        """Apresenta o plano de busca."""
        print("--- PLANO ---")
        # @TODO: Implementação do aluno
        for plannedAction in self.plan:
            print("{} > ".format(action[plannedAction]), end='')
        print("FIM\n\n")

    def deliberate(self):
        # Primeira chamada, realiza busca para elaborar um plano

        if self.counter == -1:

            self.plan = [N, N, N, NE, L, L, L, L, L, L, NE, N]

            if self.plan != None:
                self.printPlan()
            else:
                print("SOLUÇÃO NÃO ENCONTRADA")
                return -1

        # Nas demais chamadas, executa o plano já calculado
        self.counter += 1

        if self.prob.goalTest(self.positionSensor()):
            return -1

        currentAction = self.plan[self.counter]

        self.executeGo(self.plan[self.counter])
        self.currentState = self.positionSensor()

        cost = 0.0
        for i in range(-1, self.counter):
            cost += self.prob.getActionCost(self.plan[i + 1])

        print("*****************************************************")
        print("estado atual  : ({0},{1})".format(self.model.agentPos[0],
                                                 self.model.agentPos[1]))
        print("acoes possiveis:", end='')
        actions = self.prob.possibleActions(self.positionSensor())
        for i in range(0, len(actions)):
            if actions[i] != -1:
                print(" {0}".format(action[i]), end='')
        print("\nct: {0} de {1}".format(self.counter + 1, len(self.plan)))
        print("custo ate o momento (com a acao escolhida): {0}".format(cost))
        print("*****************************************************\n")

        return 1

    def executeGo(self, direction):
        """Atuador: solicita ao agente física para executar a ação.
        @param direction: Direção da ação do agente
        @return 1 caso movimentação tenha sido executada corretamente."""
        self.model.go(direction)
        return 1

    def positionSensor(self):
        """Simula um sensor que realiza a leitura do posição atual no ambiente e traduz para uma instância da classe Estado.
        @return estado que representa a posição atual do agente no labirinto."""
        pos = self.model.agentPos
        return State(pos[0], pos[1])