Beispiel #1
0
 def __init__(self,
              graph_file,
              agent_file,
              cutoff_depth,
              ping_pong,
              mode='adversarial'):
     self.ping_pong = ping_pong
     self.graph_file = graph_file
     self.time = 0  # track time of the world
     self.evacuated = 0  # total number of people evacuated
     self.agents_history = []  # search paths of smart agents
     self.cutoff_depth = int(cutoff_depth)
     self.world = World(graph_file=graph_file, k=self.prompt_k())
     self.deadline = self.world.get_deadline()
     self.agents = self.get_agents_data(agent_file=agent_file,
                                        world=self.world)
     self.init_state = self.create_init_states(self.world, self.agents)
     self.mode = mode
     if not ping_pong:
         self.game_tree = GameTree(self.init_state,
                                   self.world,
                                   self.agents,
                                   mode=mode,
                                   cutoff_depth=self.cutoff_depth)
     super(HurricaneGameSimulator, self).__init__(state=self.world,
                                                  agents=self.agents)
Beispiel #2
0
 def __init__(self, graph_file, agent_file, f):
     self.graph_file = graph_file
     self.time = 0  # track time of the world
     self.evacuated = 0  # total number of people evacuated
     self.f_constant = f
     self.agents_history = []  # search paths of smart agents
     world = World(graph_file=graph_file, k=self.prompt_k())
     self.deadline = world.get_deadline()
     agents = self.get_agents_data(agent_file=agent_file, world=world)
     super(HurricaneEvacuationSimulator, self).__init__(state=world,
                                                        agents=agents)
     self.vandal_records = {}  # pairs of <edge>:<time-of-blocking>
Beispiel #3
0
    def __init__(self, graph_file, start_vertex):
        self.graph_file = graph_file
        self.world = World(graph_file=graph_file)
        self.deadline = self.world.get_deadline()
        self.shelter_tag = self.world.get_shelter_tag()
        # create agent
        self.start_vertex = start_vertex
        self.time = 0  # track time of the world
        self.evacuated = 0  # total number of people evacuated
        self.belief_space = self.init_belief_space()

        self.val_iterator = ValueIteration(self.belief_space, self.world)
        self.utilities = self.val_iterator.value_iteration()
        print(self.utilities.values())
Beispiel #4
0
from env import World
from model2 import Model

################################################################################################
parser = argparse.ArgumentParser()
parser.add_argument('--load', type=str, default=False,help='model to load')
parser.add_argument('--out',type=str, default='DQN.pth',help='output file')
parser.add_argument('--test', action='store_const',const=True,default=False,help='testing flag')
opt = parser.parse_args()
################################################################################################
################################################################################################
################################################################################################
################################################################################################
################################################################################################
from logger import Logger
env = World()
agent = Model(opt.load,mode='DDQN')

##########################################################################
#TRAIN THE VISOR
def train(n_episodes=50000, max_t=10, print_every=1, save_every=20):

    logger = Logger('./logs')
    scores_deque = deque(maxlen=200)
    solved_deque = deque(maxlen=200)
    scores= []
    best = 0

    for i_episode in count():
        state = env.reset2_4(manual_pose=(i_episode % 200) + 1)
        score = 0
Beispiel #5
0
class HurricaneGameSimulator(Simulator):
    def __init__(self,
                 graph_file,
                 agent_file,
                 cutoff_depth,
                 ping_pong,
                 mode='adversarial'):
        self.ping_pong = ping_pong
        self.graph_file = graph_file
        self.time = 0  # track time of the world
        self.evacuated = 0  # total number of people evacuated
        self.agents_history = []  # search paths of smart agents
        self.cutoff_depth = int(cutoff_depth)
        self.world = World(graph_file=graph_file, k=self.prompt_k())
        self.deadline = self.world.get_deadline()
        self.agents = self.get_agents_data(agent_file=agent_file,
                                           world=self.world)
        self.init_state = self.create_init_states(self.world, self.agents)
        self.mode = mode
        if not ping_pong:
            self.game_tree = GameTree(self.init_state,
                                      self.world,
                                      self.agents,
                                      mode=mode,
                                      cutoff_depth=self.cutoff_depth)
        super(HurricaneGameSimulator, self).__init__(state=self.world,
                                                     agents=self.agents)

    # return num of actions for each agent
    def get_all_actions(self):
        agent_actions = {}
        for agent in self.agents:
            agent_actions[agent.name] = len(agent.get_actions())
        return agent_actions

    # return number of all people evacuated for ALL agents
    def get_total_evacuated(self):
        acc = 0
        for agent in self.agents:
            acc += agent.get_evacuated()
        return acc

    # move agent to the destination
    def move_agent_to(self, agent, dest, edge):
        agent.vertex = dest  # move the agent
        moving_time = self.calculate_price(agent=agent, edge=edge)
        self.time += moving_time  # add total time of simulator
        # if deadline has passed, return
        if self.time > self.deadline:
            return False
        if agent.observation.is_house(agent.vertex):
            agent.pick_up()
        elif agent.get_people_in_car() > 0:  # if in a Shelter vertex
            agent.drop_off()
        return True

    # time it takes to traverse on 'edge'
    def calculate_price(self, agent, edge):
        w = edge.weight
        k = self.state.get_slow_down()
        p = agent.get_people_in_car()
        return w * (1 + k * p)

    # Do a 1step for a Human & Greedy Agent
    def do_agent(self, agent):
        next_move = agent.do()  # do action for Human Agent
        agent.add_action(next_move)
        if next_move == 'NOP':
            self.time += 1
        else:  # Traverse
            if next_move[0].upper() != 'T':
                raise Exception('Unknown action')
            dest = int(next_move[1:])  # number of the destination vertex
            edge_to_traverse = self.state.get_edge(agent.vertex, dest)
            return self.move_agent_to(agent=agent,
                                      edge=edge_to_traverse,
                                      dest=dest)

    # input in the format of : H1 G3;  <Type|Vertex>
    def get_agents_data(self, world, agent_file=None):
        num_human = 0
        num_gamers = 0
        agents = []
        if agent_file is not None:
            with open(agent_file) as agents_file:
                for line in agents_file.readlines():
                    for agent_symbol in line.split():
                        vertex_number = int(agent_symbol[1:])
                        choice = 'MAX' if len(agents) == 0 else 'MIN'
                        if agent_symbol.upper().startswith('H'):
                            name = 'Human-{}'.format(str(num_human))
                            agent = Human(world=world,
                                          name=name,
                                          init_vertex=vertex_number,
                                          choice=choice)
                            agents.append(agent)
                            num_human += 1
                        elif agent_symbol.upper().startswith('G'):

                            choice = 'MAX' if len(agents) == 0 else 'MIN'
                            name = 'Gamer-{}'.format(str(num_gamers))
                            agent = GameTreeAgent(world=world,
                                                  name=name,
                                                  init_vertex=vertex_number,
                                                  choice=choice)
                            agents.append(agent)
                            num_gamers += 1

        return agents

    # prompt the user for the K  -   slow down constant
    def prompt_k(self):
        k = float(input('Enter the slow-down constant: '))
        # 0 < K < 1
        if 0 < k <= 1:
            return k
        raise Exception('K must be in range (0,1)')

    # create a path of states from the final node. the path is the agent's actions.
    def get_state_path(self, final_node):
        path = [final_node]
        if final_node == 'FAILURE':
            return ['FAILURE']
        runner_node = final_node.parent

        while runner_node is not None:
            path.insert(0, runner_node)
            runner_node = runner_node.parent
        return path

    # get the number of people saved by the Agent
    def get_score_from_path(self, state_path):
        score = 0
        for i in range(len(state_path))[1:]:
            in_car = state_path[i].get_people_in_car()
            # if 0 people in car, it means last state was a drop-off
            if in_car is 0:
                score += state_path[i - 1].get_people_in_car()
        return score

    def print_run(self):

        if len(self.agents_history) is 0:
            print('Nothing to print!')
            return
        for agent, state_path in self.agents_history:
            actions = [node.action for node in state_path]
            score = self.get_score_from_path(state_path)
            expands = self.agents[-1].expands
            p = self.f_constant * score + expands
            print('**********\nShowing steps of {}.\nscore:{}\nExpands:{}'.
                  format(agent, score, expands))
            print('Performance: {} = {} * {} + {}'.format(
                p, self.f_constant, score, expands))
            print('Final State: {}\n\n'.format(state_path[len(state_path) -
                                                          1].state))
            print('Action Trace:\n    {}\n'.format(actions))

    # create a state for 2 agent problem
    def create_init_states(self, world, agents):
        state = dict()
        for agent in agents:
            people = world.get_vertex_for_tag(
                agent.vertex).people if world.is_house(agent.vertex) else 0
            state[agent.name] = {
                'position': agent.vertex,
                'people_in_car': people,
                'people_saved': 0
            }
        state['time'] = 0
        return state

    # run each agent in turn. in case of human agent, CHANGE the parent according to the human's choice.
    def run(self):
        print('initial state : {}'.format(self.game_tree.root.get_state()))
        node = self.game_tree.root
        i = 0  # first agent to "run"
        while node.type is not 'CUTOFF' and node.type is not 'TERMINAL':
            agent = self.agents[i]
            action = agent.get_move(node)
            # update to next node
            for child in node.children:
                if child.action == action:
                    child.parent = node
                    node = child
            state_path = self.get_state_path(node)
            print('path here : {}'.format([n.action for n in state_path]))
            print(
                '------\nagent:{} action {}\ntime: {}\nminimax value: {}\nstate: {}\n------\n'
                .format(agent.name, action, node.get_time(),
                        node.get_minimax_value(), node.get_state()))
            # next agent
            i = (i + 1) % len(self.agents)

    def run_ping_pong(self):
        turn = 0
        actions = []
        visited = []
        state = self.create_init_states(self.world, self.agents)
        visited.append(
            state[self.agents[0].name]['position'])  # append initial positions
        visited.append(
            state[self.agents[1].name]['position'])  # append initial positions
        while True:
            current_agent = self.agents[turn]
            if isinstance(current_agent, Human):
                result_node = current_agent.get_move(state=state,
                                                     visited=visited,
                                                     world=self.world)
            else:
                result_node = current_agent.get_move_new_tree(
                    state=state,
                    visited=visited,
                    world=self.world,
                    cutoff_depth=self.cutoff_depth,
                    mode=self.mode)
            actions.append(result_node.action)
            visited.append(result_node.get_position(current_agent.name))
            visited.append(result_node.get_position(current_agent.name))

            print('path here : {}'.format(actions))
            print(
                '------\nagent:{} action {}\ntime: {}\nminimax value: {}\nstate: {}\n------\n'
                .format(self.agents[turn].choice, result_node.action,
                        result_node.get_time(),
                        result_node.get_minimax_value(),
                        result_node.get_state()))

            if result_node.type == 'CUTOFF' or result_node.type == 'TERMINAL':
                print("final state: {}".format(result_node.get_state()))
                break
            turn = (turn + 1) % len(self.agents)  # next agent's turn
            state = result_node.get_state()
            result_node = None
Beispiel #6
0
class HurricaneEvacuationSimulator(object):
    def __init__(self, graph_file, start_vertex):
        self.graph_file = graph_file
        self.world = World(graph_file=graph_file)
        self.deadline = self.world.get_deadline()
        self.shelter_tag = self.world.get_shelter_tag()
        # create agent
        self.start_vertex = start_vertex
        self.time = 0  # track time of the world
        self.evacuated = 0  # total number of people evacuated
        self.belief_space = self.init_belief_space()

        self.val_iterator = ValueIteration(self.belief_space, self.world)
        self.utilities = self.val_iterator.value_iteration()
        print(self.utilities.values())

    # initialize the belief space for the graph
    def init_belief_space(self):
        bs = BeliefSpace(self.world, init_vertex=int(args.start_vertex))
        bs.create_all_belief_states(self.start_vertex)
        return bs

    # generate all possible blockage combinations
    def all_blockage_instances(self):
        # edge that can be blocked
        maybe_blocked = map(
            lambda e: e.edge_num,
            filter(lambda e: e.prob_blockage > 0,
                   self.world.get_edges(one_way=True)))
        blockages = set(product({True, False}, repeat=len(maybe_blocked)))
        return [dict(zip(maybe_blocked, blockage)) for blockage in blockages]

    def random_blockage(self):
        # blockable edges
        blockables = map(
            lambda e: e.edge_num,
            filter(lambda e: e.prob_blockage > 0,
                   self.world.get_edges(one_way=True)))
        # NONE at first
        blockage_dict = {key: None for key in blockables}
        for e in blockage_dict:
            prob = self.world.get_edge_for_num(e).prob_blockage
            blockage_dict[e] = self.true_in_prob(prob)

        return blockage_dict

    # return 'True' in probability of 'prob'
    def true_in_prob(self, prob):

        rand = random.random()
        return True if rand <= prob else False

    def run_an_agent(self, times=10000):
        util_acc = 0.0
        init_s = None
        for i in range(times):
            blockage_instance = self.random_blockage()
            init_states = self.belief_space.init_states
            # remove from init state/s
            init_state = filter(
                lambda d: self.consistent_state(d, blockage_instance),
                init_states)[0]
            init_s = init_state
            agent = PlanningAgent(world=self.world, belief_space=self.belief_space, utilities=self.utilities, \
                                  init_state=init_state, init_vertex=self.start_vertex, blockage=blockage_instance)
            next_state = agent.state
            while not self.belief_space.goal_state(next_state) and not (len(
                    next_state.successors) == 0):
                next_state = agent.do()
            util_acc += self.utilities[
                next_state]  #self.belief_space.states.index(next_state)]
            print('i: {}\nacc: {}'.format(i, util_acc))
        #print('accumulated: {}'.format(util_acc))
        print('average: {}'.format(util_acc / times))
        print('init value: {}'.format(
            self.utilities[self.belief_space.states[0]]))

    def consistent_state(self, belief_state, blockage_instance):
        state_blocked = belief_state.blocked_edges
        for edge_num in state_blocked:
            if blockage_instance[edge_num] != state_blocked[edge_num]:
                return False
        return True
Beispiel #7
0
 def __init__(self, graph_file):
     self.graph_file = graph_file
     self.world = World(graph_file=graph_file)
     self.deadline = self.world.get_deadline()
     self.bayes_network = BayesNetwork(world=self.world)
     self.reports = {}
Beispiel #8
0
class Main(object):
    def __init__(self, graph_file):
        self.graph_file = graph_file
        self.world = World(graph_file=graph_file)
        self.deadline = self.world.get_deadline()
        self.bayes_network = BayesNetwork(world=self.world)
        self.reports = {}

    def clear_screen(self, stupid=False):
        if stupid:
            print('\n') * 100
        else:
            os.system('cls' if os.name == 'nt' else 'clear')

    def get_numbers(self, prompt, smallest, biggest):
        while True:
            choice = raw_input(prompt).split()
            if 'exit' in choice or 'quit' in choice or 'q' in choice:
                exit()

            elif not any(
                    int(x) < smallest or int(x) > biggest
                    for x in choice) and not len(choice) == 0:
                # self.clear_screen(stupid=True)
                return choice

            else:
                # self.clear_screen(stupid=True)
                print('illegal input.')
                return False

    # get query evidence from user
    def prompt_query_evidence(self):
        all_reports = {}
        num_edges = len(self.world.get_edges(one_way=True))
        num_vertices = len(self.world.get_vertices())
        report_prompt = 'What would you like to report? \n 1. Flood\n 2. Blockage\n 3. Evacuees\n-------\n ' \
                        '4. No Flood\n 5. No Blockage\n 6. No Evacuees\n-------\n 7. Non-Blocked Path\n 8. Print Reasoning\n 9. Bonus\n 10. Reset\n choice: '
        short_report_prompt = '\nAnother report?'
        blockage_prompt = 'report Blocking at edges : range-({},{}) '.format(
            1, num_edges)
        flooding_prompt = 'report Flooding at vertices range-({},{}) : '.format(
            1, num_vertices)
        evacuees_prompt = 'report Evacuees at vertices range-({},{}): '.format(
            1, num_vertices)
        non_blockage_prompt = 'report NON Blocking at edges : range-({},{}) '.format(
            1, num_edges)
        non_flooding_prompt = 'report NON Flooding at vertices range-({},{}) : '.format(
            1, num_vertices)
        non_evacuees_prompt = 'report NON Evacuees at vertices range-({},{}): '.format(
            1, num_vertices)
        iteration = 0
        while True:
            iteration += 1
            print(
                '\n----------------\nReported so far :  \n{}\n----------------'
                .format(all_reports))
            if iteration is 1:
                report_choice = int(
                    self.get_numbers(report_prompt, smallest=1, biggest=10)[0])
            else:
                report_choice = int(
                    self.get_numbers(short_report_prompt,
                                     smallest=1,
                                     biggest=10)[0])
            if report_choice == 1:
                floodings = set(
                    self.get_numbers(flooding_prompt,
                                     smallest=1,
                                     biggest=num_vertices))
                floodings = set(['flooding ' + str(num) for num in floodings])
                for report in floodings:
                    all_reports[report] = True

            elif report_choice == 2:
                blockages = set(
                    self.get_numbers(blockage_prompt,
                                     smallest=1,
                                     biggest=num_edges))
                blockages = set(['blockage ' + str(num) for num in blockages])
                for report in blockages:
                    all_reports[report] = True

            elif report_choice == 3:
                evacuees = set(
                    self.get_numbers(evacuees_prompt,
                                     smallest=1,
                                     biggest=num_vertices))
                evacuees = set(['evacuees ' + str(num) for num in evacuees])
                for report in evacuees:
                    all_reports[report] = True

            elif report_choice == 4:
                floodings = set(
                    self.get_numbers(non_flooding_prompt,
                                     smallest=1,
                                     biggest=num_vertices))
                floodings = set(['flooding ' + str(num) for num in floodings])
                for report in floodings:
                    all_reports[report] = False

            elif report_choice == 5:
                blockages = set(
                    self.get_numbers(non_blockage_prompt,
                                     smallest=1,
                                     biggest=num_edges))
                blockages = set(['blockage ' + str(num) for num in blockages])
                for report in blockages:
                    all_reports[report] = False

            elif report_choice == 6:
                evacuees = set(
                    self.get_numbers(non_evacuees_prompt,
                                     smallest=1,
                                     biggest=num_vertices))
                evacuees = set(['evacuees ' + str(num) for num in evacuees])
                for report in evacuees:
                    all_reports[report] = False

            elif report_choice == 7:
                print('Overall Reported: {}'.format(all_reports))
                prompt = 'Enter a set of Edges as a path. range-({},{}) '.format(
                    1, num_edges)
                path = set(
                    int(n) for n in self.get_numbers(
                        prompt, smallest=1, biggest=num_edges))
                if len(path) > 1:
                    self.reports = all_reports
                    p = self.get_probability_path_free(path)
                    non_blocked = ', '.join(
                        ['not blockage {}'.format(str(e)) for e in path])
                    given = self.evidence_as_string(all_reports)
                    s = 'P({of} | {given} ) = {p}'.format(of=non_blocked,
                                                          given=given,
                                                          p=p)
                    print(s)
                else:
                    print('A single edge can computed normally')

            elif report_choice == 8:
                print('Overall Reported: {}'.format(all_reports))
                self.reports = all_reports
                self.perform_reasoning()

            elif report_choice == 9:
                self.reports = all_reports
                print('Overall Reported: {}'.format(all_reports))
                prompt = 'Enter a source Vertex and a Destination Vertex. range-({},{}) '.format(
                    1, num_vertices)
                user_input = [
                    int(n) for n in self.get_numbers(
                        prompt, smallest=1, biggest=num_vertices)
                ]
                if len(user_input) is not 2:
                    print('usage : <source> <destination>')
                else:
                    self.reports = all_reports
                    self.do_bonus(source=user_input[0],
                                  destination=user_input[1])

            elif report_choice == 10:
                all_reports = dict()

    # print the network
    def print_network(self):
        self.bayes_network.print_network()

    def perform_reasoning(self):
        self.query_type('evacuees')
        self.query_type('flooding')
        self.query_type('blockage')

    def query_type(self, node_type, for_print=True):
        nodes = self.bayes_network.get_nodes_of_type(node_type)
        vals = []
        for node in nodes:
            # self.enumerate_prob(node)
            if node.node_type != 'blockage':
                vals.append((node.get_vertex().tag, self.enumerate_prob(node)))
            else:
                vals.append(
                    (node.get_edge().edge_num, self.enumerate_prob(node)))
        return vals

    def do_bonus(self, source, destination):
        paths = self.world.all_paths(source=source, destination=destination)
        probabilities = [self.get_probability_path_free(p) for p in paths]
        print(
            'Printing the Probability of free from blockages - path from {} to {} :'
            .format(source, destination))
        min_path = ([], 0.0)
        for (path, prob) in zip(paths, probabilities):
            if prob >= min_path[1]:
                min_path = (path, prob)
            print('Path: {} , Probability(free) = {}'.format(path, prob))
        print('\n===========================\n')
        if min_path[1] == 0.0:
            print('all paths from {} to {} are blocked with probability 1'.
                  format(source, destination))
        else:
            print('Best path is : {} with probability {}'.format(
                min_path[0], min_path[1]))

    # and print
    def enumerate_prob(self, node):
        enumerator = Enumerator(query_var=node,
                                evidence=self.reports,
                                network=self.bayes_network)
        p = enumerator.pretty_string(query_value=True)
        p_val = enumerator.enumeration_ask()
        s = p + str(p_val[0])
        print(s)
        # print("\n")
        return p_val[0]

    def get_probability_path_free(self, path):
        reported_evidence = self.reports.copy()
        query_vars = filter(lambda n: n.get_edge().edge_num in path,
                            self.bayes_network.get_nodes_of_type('blockage'))
        multi_query = MultiQuery(query_vars=query_vars,
                                 evidence=reported_evidence,
                                 network=self.bayes_network)
        # vars_true is False - we want blockages to be false.
        p = multi_query.query_to_value(vars_true=False)

        return p

    def evidence_as_string(self, evidence):
        s = ''
        for e in evidence.keys():
            if s != '':
                s += ','
            if evidence[e]:
                s += e
            else:
                s += 'not ' + e
        return s
Beispiel #9
0
class HurricaneEvacuationSimulator(Simulator):
    def __init__(self, graph_file, agent_file, f):
        self.graph_file = graph_file
        self.time = 0  # track time of the world
        self.evacuated = 0  # total number of people evacuated
        self.f_constant = f
        self.agents_history = []  # search paths of smart agents
        world = World(graph_file=graph_file, k=self.prompt_k())
        self.deadline = world.get_deadline()
        agents = self.get_agents_data(agent_file=agent_file, world=world)
        super(HurricaneEvacuationSimulator, self).__init__(state=world,
                                                           agents=agents)
        self.vandal_records = {}  # pairs of <edge>:<time-of-blocking>

    # return num of actions for each agent
    def get_all_actions(self):
        agent_actions = {}
        for agent in self.agents:
            agent_actions[agent.name] = len(agent.get_actions())
        return agent_actions

    # return number of all people evacuated for ALL agents
    def get_total_evacuated(self):
        acc = 0
        for agent in self.agents:
            acc += agent.get_evacuated()
        return acc

    # move agent to the destination
    def move_agent_to(self, agent, dest, edge):
        agent.vertex = dest  # move the agent
        moving_time = self.calculate_price(agent=agent, edge=edge)
        self.time += moving_time  # add total time of simulator
        # if deadline has passed, return
        if self.time > self.deadline:
            return False
        if agent.observation.is_house(
                agent.vertex) and not isinstance(agent, Vandal):
            agent.pick_up()
        elif agent.get_people_in_car() > 0:  # if in a Shelter vertex
            agent.drop_off()
        return True

    # time it takes to traverse on 'edge'
    def calculate_price(self, agent, edge):
        w = edge.weight
        k = self.state.get_slow_down()
        p = agent.get_people_in_car()
        return w * (1 + k * p)

    # Do a 1step for a Human & Greedy Agent
    def do_agent(self, agent):
        next_move = agent.do()  # do action for Human Agent
        agent.add_action(next_move)
        if next_move == 'NOP':
            self.time += 1
        else:  # Traverse
            if next_move[0].upper() != 'T':
                raise Exception('Unknown action')
            dest = int(next_move[1:])  # number of the destination vertex
            edge_to_traverse = self.state.get_edge(agent.vertex, dest)
            return self.move_agent_to(agent=agent,
                                      edge=edge_to_traverse,
                                      dest=dest)

    # Do a step for a Vandal Agent
    def do_vandal(self, agent):
        next_move = agent.do()  # do action for Vandal Agent
        agent.add_action(next_move)
        if next_move == 'NOP':
            self.time += 1
        elif str(next_move).startswith('BLOCK'):
            v1 = int(next_move.split()[1])
            v2 = int(next_move.split()[2])
            to_block = self.state.get_edge(v1, v2)
            to_block.blocked = True
            self.time += 1
            self.record_block(v1, v2)
        else:  # Traverse
            if next_move[0].upper() != 'T':
                raise Exception('Unknown action')
            dest = int(next_move[1:])  # number of the destination vertex
            edge_to_traverse = self.state.get_edge(agent.vertex, dest)
            return self.move_agent_to(agent=agent,
                                      edge=edge_to_traverse,
                                      dest=dest)

    # Do a step for a Vandal Agent
    def simulate_vandal(self, agent):
        while self.time <= self.deadline:
            self.do_vandal(agent=agent)
        # re-create the world
        self.state = World(graph_file=self.graph_file,
                           k=self.state.get_slow_down())

    # input in the format of : H1 V3 G10 H2 ;  <Type|Vertex>

    def get_agents_data(self, world, agent_file=None):
        num_human = 0
        num_greedy = 0
        num_vandal = 0
        agents = []
        if agent_file is not None:
            with open(agent_file) as agents_file:
                for line in agents_file.readlines():
                    for agent_symbol in line.split():
                        vertex_number = int(agent_symbol[1:])
                        if agent_symbol.upper().startswith('H'):
                            agent = Human(world=world,
                                          name='Human-{}'.format(
                                              str(num_human)),
                                          init_vertex=vertex_number)
                            num_human += 1
                        elif agent_symbol.upper().startswith('G'):
                            agent = Greedy(world=world,
                                           name='Greedy-{}'.format(
                                               str(num_greedy)),
                                           init_vertex=vertex_number)
                            num_greedy += 1
                        else:  # agent_symbol.upper().startswith('V')
                            agent = Vandal(world=world,
                                           name='Vandal-{}'.format(
                                               str(num_vandal)),
                                           init_vertex=vertex_number)
                            num_vandal += 1
                        agents.append(agent)

        return agents

    # prompt the user for the K  -   slow down constant
    def prompt_k(self):
        k = 1  #float(input('Enter the slow-down constant: '))
        # 0 < K < 1
        if 0 < k <= 1:
            return k
        raise Exception('K must be in range (0,1)')

    def run_task1(self):
        print('DEADLINE IS {}'.format(self.deadline))
        # First round of pick-ups
        for agent in self.agents:
            if isinstance(agent, Human) or isinstance(agent, Greedy):
                agent.pick_up()
        while self.time < self.deadline:
            for agent in self.agents:
                if isinstance(agent, Human) or isinstance(agent, Greedy):
                    if isinstance(agent, Human):
                        agent.print_agent_status()
                    if self.do_agent(agent=agent) is False:
                        continue
                if isinstance(agent, Vandal):
                    if self.do_vandal(agent=agent) is False:
                        break
                if self.time >= self.deadline:
                    break
                print('Time : {}\n---------'.format(self.time))
                agent.print_agent_status()
                # self.state.print_graph()
                print('----step done, time {}----\n\n'.format(self.time))

    def run_task2(self, expand_limit, agent="greedy"):
        agent_type = agent
        print(agent_type)
        if agent_type.lower() == "greedy":
            smart_agent = SmartGreedy(world=self.state,
                                      name='SmartGreedy',
                                      init_vertex=1)
        elif agent_type.lower() == "a*":
            smart_agent = SmartAStar(world=self.state,
                                     name='SmartAStar',
                                     init_vertex=1)
        else:  #if agent.upper() is "RTA":
            smart_agent = SmartRTA(world=self.state,
                                   name='RTA',
                                   init_vertex=1,
                                   expand_limit=expand_limit)

        self.agents.append(smart_agent)
        final_node = smart_agent.do()
        self.agents_history.append(
            (agent_type, self.get_state_path(final_node)))
        self.print_run()

    def run_bonus(self, expand_limit, agent="greedy", vandal_init_vertex=1):

        vandal = Vandal(world=self.state,
                        init_vertex=vandal_init_vertex,
                        name='Vandal_Agents')
        self.simulate_vandal(vandal)  # run the vandal
        print(
            '------------\nThe Vandal records are: {}\n------------\n'.format(
                self.vandal_records))
        agent_type = agent
        print(agent_type)
        if agent_type.lower() == "greedy":
            smart_agent = SmartGreedy(world=self.state,
                                      name='SmartGreedy',
                                      init_vertex=1,
                                      bonus_vandal_records=self.vandal_records)
        elif agent_type.lower() == "a*":
            smart_agent = SmartAStar(world=self.state,
                                     name='SmartAStar',
                                     init_vertex=1,
                                     bonus_vandal_records=self.vandal_records)
        else:  #if agent.upper() is "RTA":
            smart_agent = SmartRTA(world=self.state,
                                   name='RTA',
                                   init_vertex=1,
                                   expand_limit=expand_limit,
                                   bonus_vandal_records=self.vandal_records)

        self.agents.append(smart_agent)
        final_node = smart_agent.do()
        self.agents_history.append(
            (agent_type, self.get_state_path(final_node)))
        self.print_run()

        # vandal = Vandal(world=self.state, init_vertex=vandal_init_vertex, name='Vandal_Agents')
        #
        # agent_type = agent
        # print(agent_type)
        # if agent_type.lower() == "greedy":
        #     smart_agent = SmartGreedy(world=self.state, name='SmartGreedy', init_vertex=1)
        # elif agent_type.lower() == "a*":
        #     smart_agent = SmartAStar(world=self.state, name='SmartAStar', init_vertex=1)
        # else: #if agent.upper() is "RTA":
        #     smart_agent = SmartRTA(world=self.state, name='RTA', init_vertex=1, expand_limit=expand_limit)
        #
        # self.agents.append(smart_agent)
        # final_node = smart_agent.do()
        # nodes = smart_agent.search_tree.get_visited_vertices(final_node)
        # smart_node = nodes[-1]
        #
        # while smart_node.get_time() <= self.deadline:
        #     # "advance" the smart agent one step
        #     smart_node = smart_agent.search_tree.get_next_node_in_path(smart_node, final_node)
        #     state = smart_node.get_state()
        #     # advance time as the smart agent's step
        #     self.time = smart_node.get_time()
        #     # run one step of the vandal
        #     self.do_vandal(vandal)
        #     # state[]

    # create a path of states from the final node. the path is the agent's actions.
    def get_state_path(self, final_node):
        path = [final_node]
        if final_node == 'FAILURE':
            return ['FAILURE']
        runner_node = final_node.parent

        while runner_node is not None:
            path.insert(0, runner_node)
            runner_node = runner_node.parent
        return path

    # get the number of people saved by the Agent
    def get_score_from_path(self, state_path):
        score = 0
        for i in range(len(state_path))[1:]:
            in_car = state_path[i].get_people_in_car()
            # if 0 people in car, it means last state was a drop-off
            if in_car is 0:
                score += state_path[i - 1].get_people_in_car()
        return score

    # def get_rescue_list_from_path(self, state_path):
    #     rescue_list = []
    #     for i in range(len(state_path)):
    #         rescue_list.append(' ')
    #         in_car = state_path[i].get_people_in_car()
    #         if in_car > state_path[i - 1].get_people_in_car():
    #             rescue_list[i] = 'picked up : {}'.format(in_car)
    #         elif in_car < state_path[i - 1].get_people_in_car():
    #             rescue_list[i] = 'dropped off : {}'.format(state_path[i - 1].get_people_in_car())
    #     return rescue_list

    def print_run(self):

        if len(self.agents_history) is 0:
            print('Nothing to print!')
            return
        for agent, state_path in self.agents_history:
            actions = [node.action for node in state_path]
            score = self.get_score_from_path(state_path)
            expands = self.agents[-1].expands
            p = self.f_constant * score + expands
            print('**********\nShowing steps of {}.\nscore:{}\nExpands:{}'.
                  format(agent, score, expands))
            print('Performance: {} = {} * {} + {}'.format(
                p, self.f_constant, score, expands))
            print('Final State: {}\n\n'.format(state_path[len(state_path) -
                                                          1].state))
            print('Action Trace:\n    {}\n'.format(actions))

    def record_block(self, v1, v2):
        edge1 = '{},{}'.format(str(v1), str(v2))
        edge2 = '{},{}'.format(str(v2), str(v1))
        self.vandal_records[edge1] = self.time
        self.vandal_records[edge2] = self.time
Beispiel #10
0
 def simulate_vandal(self, agent):
     while self.time <= self.deadline:
         self.do_vandal(agent=agent)
     # re-create the world
     self.state = World(graph_file=self.graph_file,
                        k=self.state.get_slow_down())