Пример #1
0
def test_random_key():
    import string

    r = RandomDict()
    for k in string.ascii_lowercase:
        r[k] = 1
    keyset = set(string.ascii_lowercase)

    while len(r) > 0:
        k = r.random_key()
        assert k in keyset
        del r[k]
Пример #2
0
fTrees = io.open("./DictStore.pkl", 'r').read().splitlines()

singleRunResults = RandomDict()

key = "DEFAULT, SHOULD NEVER BE SEEN"

for line in fTrees:
    if line[0] == '.':
        key = line
        singleRunResults[key] = []
    else:
        tDict = eval(line)
        root = importer.import_(tDict)
        singleRunResults[key].append(root)

done = 0

for x in singleRunResults.keys:
    for y in range(0, 10):
        t = time.time()
        z = singleRunResults.random_key()
        while (z == x or z == x[:-5] + '2.txt'):
            z = singleRunResults.random_key()
        comp = treeTester.runDouble(singleRunResults[x], singleRunResults[z])
        t = time.time() - t
        output = x + ", " + z + ", " + str(comp) + ", " + str(t) + "\n"
        print output
        done += 1
        print done
        fNaive.write(unicode(output))
Пример #3
0
def genquery(genomeFile, jellyFile, totedits, medindel, insprob, delprob,
             queryfreq, querycount, outputFile):
    #genome - path to genome
    #totedits - total number of edits to make
    #medindel - median (mean) size of indel edits. actual edit length determined from gaussian with mean medindel and std medindel/2
    #insprob - probability of insertion
    #delprob - probability of deletion
    #outputs all edits into a text file called "sampleedits.txt"

    if delprob + insprob > 1.0:
        raise "Error, delprob = {} and insprob = {}. "\
              "The sum is {} > 1.0".format(
                delprob, insprob, delprob + insprob)

    genome = genomeFile.readline()
    genomeFile.close()
    #mf = jellyfish.ReadMerFile(jellyFile)
    qf = jellyfish.QueryMerFile(jellyFile)
    numbases = len(genome) - 1
    genome = genome[0:numbases]
    letters = ['A', 'C', 'G', 'T']
    randr = []
    allinds = []
    snpProb = 1.0 - (insprob + delprob)
    SNPrange = int(snpProb * totedits)
    insrange = int(insprob * totedits)
    delrange = int(delprob * totedits)

    editTypes = (['S'] * SNPrange) +\
                (['D'] * delrange) +\
                (['I'] * insrange)

    random.shuffle(editTypes)
    qcount = 0
    #effectedkmers = dict()
    effectedkmers = RandomDict()
    count = 0
    sample = 10
    for val in editTypes:
        qcount += 1
        if val == 'I':
            p, s, seq = random_insertion(numbases, medindel)
            numbases += s
            outputFile.write('I %d %s\n' % (p, seq))
            if ((qcount - 1) % sample) == 0:
                add_kmers_in_seq(effectedkmers, seq)
                add_kmers_in_seq(effectedkmers, genome[p - K + 1:p + K])

        elif val == 'D':
            p, s = random_deletion(numbases, medindel)
            numbases -= s
            outputFile.write('D %d %d\n' % (p, p + s - 1))
            #add_kmers_in_seq(effectedkmers, genome[p-K+1:p+s-1+K])

        else:
            p, seq = random_snp(numbases)
            outputFile.write('S %d %s\n' % (p, seq))

            if ((qcount - 1) % sample) == 0:
                add_kmers_in_seq(effectedkmers, genome[p - K + 1:p + K - 1])

        # if it's time to output some queries
        if qcount == queryfreq:
            qcount = 0
            for qlist in xrange(querycount):
                dart = random.random()
                if dart <= EDIT_QUERY_PROB:
                    kmer = effectedkmers.random_key()
                    #kmer = random.choice(effectedkmers.keys())
                    #kmer = random.sample(effectedkmers, 1)[0]
                    editflag = 'I'
                else:
                    p = random.randrange(K * 2, numbases - K * 2)
                    kmer = genome[p:p + K].upper()
                    editflag = 'N'

                kcount = 0
                #kcount = int(qf[jellyfish.MerDNA(kmer)])
                outputFile.write('Q %s %s %d\n' % (kmer, editflag, kcount))

    outputFile.close()
Пример #4
0
class Simulation:
    """
    Class for containing the elements of the simulation.
    
    Attributes
    ----------
    time : int
        stores the time elapsed in the simulation
    
    num_taxis : int
        how many taxis there are
    
    request_rate : float
        rate of requests per time period
    
    hard_limit : int
        max distance from which a taxi is still assigned to a request
    
    taxis : dict
        storing all Taxi() instances in a dict
        keys are `taxi_id`s
    
    latest_taxi_id : int
        shows latest given taxi_id
        used or generating new taxis
    
    taxis_available : list of int
        stores `taxi_id`s of available taxis
    
    taxis_to_request : list of int
        stores `taxi_id`s of taxis moving to serve a request
    
    taxis_to_destination : list of int
        stores `taxi_id`s of taxis with passenger
    
    requests : dict
        storing all Request() instances in a dict
        keys are `request_id`s
    
    latest_request_id : int
        shows latest given request_id
        used or generating new requests
    
    requests_pending : list of int
        requests waiting to be served
    
    requests_in_progress : list of int
        requests with assigned taxis
    
    requests_dropped : list of int
        unsuccessful requests
    
    city : City
        geometry of class City() underlying the simulation
        
    show_map_labels : bool
    
    """
    def __init__(self, **config):

        # initializing time
        self.time = 0

        self.num_taxis = config["num_taxis"]
        self.request_rate = config["request_rate"]

        if "price_fixed" in config:
            # price that is used for every trip
            self.price_fixed = config["price_fixed"]
        else:
            self.price_fixed = 0

        if "price_per_dist" in config:
            # price per unit distance while carrying a passenger
            self.price_per_dist = config["price_per_dist"]
        else:
            self.price_per_dist = 1

        if "cost_per_unit" in config:
            # cost per unit distance (e.g. gas)
            self.cost_per_unit = config["cost_per_unit"]
        else:
            self.cost_per_unit = 0

        if "cost_per_time" in config:
            # cost per time (e.g. amortization)
            self.cost_per_time = config["cost_per_time"]
        else:
            self.cost_per_time = 0

        if "matching" in config:
            self.matching = config["matching"]

        if "batch_size" in config:
            self.batch_size = config["batch_size"]

        if "max_time" in config:
            self.max_time = config["max_time"]

        # this is done now by the config generator in theory
        if "max_request_waiting_time" in config:
            self.max_request_waiting_time = config["max_request_waiting_time"]
        else:
            self.max_request_waiting_time = 10000

        if ("batch_size" in config) and ("max_time" in config):
            self.num_iter = int(np.ceil(self.max_time / self.batch_size))
        else:
            self.num_iter = None

        if "behaviour" in config:  # goback / stay / cruise
            self.behaviour = config["behaviour"]
        else:
            self.behaviour = "go_back"

        if "initial_conditions" in config:  # base / home
            self.initial_conditions = config["initial_conditions"]
        else:
            self.initial_conditions = "base"

        if "reset_time" in config:
            self.reset_time = config["reset_time"]
        else:
            self.reset_time = self.max_time + 1

        # initializing counters
        self.latest_taxi_id = 0
        self.latest_request_id = 0

        # initializing object storage
        self.taxis = RandomDict()
        self.taxis_available = RandomDict()
        self.taxis_to_request = set()
        self.taxis_to_destination = set()

        self.requests = RandomDict()
        self.requests_pending = set()

        # speeding up going through requests in the order of waiting times
        # they are pushed into a deque in the order of timestamps
        self.requests_pending_deque = deque()
        self.requests_pending_deque_batch = deque(
            maxlen=self.max_request_waiting_time)
        self.requests_pending_deque_temporary = deque()
        self.requests_in_progress = set()

        # city layout
        self.city = City(**config)
        # length of pregenerated random number storage
        self.city.length = int(min(self.max_time * self.request_rate, 1e6))

        # whether to log all movements for debugging purposes
        self.log = config["log"]
        self.city.log = self.log
        # showing map of moving taxis in interactive jupyter notebook
        self.show_plot = config["show_plot"]

        # initializing simulation with taxis
        for t in range(self.num_taxis):
            self.add_taxi()

        self.taxi_df = pd.DataFrame.from_dict(
            [dict(v) for k, v in self.taxis.items()])
        self.taxi_df.set_index('taxi_id', inplace=True)

        if self.show_plot:
            # plotting variables
            self.canvas = plt.figure()
            self.canvas_ax = self.canvas.add_subplot(1, 1, 1)
            self.canvas_ax.set_aspect('equal', 'box')
            self.cmap = plt.get_cmap('viridis')
            self.taxi_colors = list(np.linspace(0, 0.85, self.num_taxis))
            shuffle(self.taxi_colors)
            self.show_map_labels = config["show_map_labels"]
            self.show_pending = config["show_pending"]
            self.init_canvas()

    def init_canvas(self):
        """
        Initialize plot.
        
        """
        self.canvas_ax.clear()
        self.canvas_ax.set_xlim(-0.5, self.city.n - 0.5)
        self.canvas_ax.set_ylim(-0.5, self.city.m - 0.5)

        self.canvas_ax.tick_params(length=0)
        self.canvas_ax.xaxis.set_ticks(list(range(self.city.n)))
        self.canvas_ax.yaxis.set_ticks(list(range(self.city.m)))
        if not self.show_map_labels:
            self.canvas_ax.xaxis.set_ticklabels([])
            self.canvas_ax.yaxis.set_ticklabels([])

        self.canvas_ax.set_aspect('equal', 'box')
        self.canvas.tight_layout()
        self.canvas_ax.grid()

    def add_taxi(self):
        """
        Create new taxi.
        
        """

        # adding home coordinates, starting taxi
        home = self.city.create_taxi_home_coords()

        if self.initial_conditions == "base":
            # create a taxi at the base
            tx = Taxi(self.city.base_coords, self.latest_taxi_id)
        elif self.initial_conditions == "home":
            # create a taxi at home
            tx = Taxi(home, self.latest_taxi_id)
        tx.home = home

        # add to taxi storage
        self.taxis[self.latest_taxi_id] = tx
        # add to available taxi matrix
        self.city.A[self.city.coordinate_dict_ij_to_c[tx.x][tx.y]].add(
            self.latest_taxi_id)
        # add to available taxi storage
        self.taxis_available[self.latest_taxi_id] = tx
        # increase counter
        self.latest_taxi_id += 1

    def add_request(self):
        """
        Create new request.
        
        """
        # here we randomly choose a place for the request
        # the random coordinates are pre-stored in a deque for faster access
        # if there are no more pregenerated coordinates in the deque, we generate some more

        # origin and destination coordinates
        ox, oy, dx, dy = self.city.create_one_request_coord()
        r = Request([ox, oy], [dx, dy], self.latest_request_id, self.time)

        # add to request storage
        self.requests[self.latest_request_id] = r
        # add to free users
        self.requests_pending_deque.append(self.latest_request_id)
        # increase counter
        self.latest_request_id += 1

    def go_to_base(self, taxi_id, bcoords):
        """
        This function sends the taxi to the base rom wherever it is.
        """

        # fetch object
        t = self.taxis[taxi_id]

        # actual coordinates
        acoords = [t.x, t.y]
        # path between actual coordinates and destination
        path = self.city.create_path(acoords, bcoords)

        # erase path memory
        t.with_passenger = False
        t.to_request = False
        t.available = True
        #        print("Erasing path memory, Taxi "+str(taxi_id)+".")
        t.next_destination = deque()
        # put path into taxi path queue
        #        print("Filling path memory, Taxi "+str(taxi_id)+". Path ",path)
        t.next_destination.extend(path)

        # put object back to its place
        self.taxis[taxi_id] = t

    def go_home_everybody(self):
        """
        Drop requests that are currently executing, and set taxis as available at their home locations.
        """
        for taxi_id in self.taxis:
            tx = self.taxis[taxi_id]

            if taxi_id in self.taxis_available:
                # (magic wand) Apparate taxi home!
                self.city.A[self.city.coordinate_dict_ij_to_c[tx.x][
                    tx.y]].remove(taxi_id)
                self.city.A[self.city.coordinate_dict_ij_to_c[tx.home[0]][
                    tx.home[1]]].add(taxi_id)
                tx.x, tx.y = tx.home

            if taxi_id in self.taxis_to_destination:
                # if somebody is sitting in it, finish request
                self.dropoff_request(tx.actual_request_executing,
                                     mode="going_home")

            if taxi_id in self.taxis_to_request:
                # if it was only going towards a request, cancel it
                self.dropoff_request(tx.actual_request_executing,
                                     mode="cancel")

            self.taxis[taxi_id] = tx

    def cruise(self, taxi_id):
        return None

    def assign_request(self, request_id, taxi_id):
        """
        Given a request_id, taxi_id pair, this function makes the match.
        It sets new state variables for the request and the taxi, updates path of the taxi etc.
        """
        r = self.requests[request_id]
        t = self.taxis[taxi_id]

        # pair the match
        t.actual_request_executing = request_id
        r.taxi_id = taxi_id

        # remove taxi from the available ones
        self.city.A[self.city.coordinate_dict_ij_to_c[t.x][t.y]].remove(
            taxi_id)
        del self.taxis_available[taxi_id]
        t.with_passenger = False
        t.available = False
        t.to_request = True

        # mark taxi as moving to request
        self.taxis_to_request.add(taxi_id)

        # forget the path that has been assigned
        t.next_destination = deque()

        # create new path: to user, then to destination
        path = self.city.create_path([t.x, t.y], [r.ox, r.oy]) + \
            self.city.create_path([r.ox, r.oy], [r.dx, r.dy])[1:]
        t.next_destination.extend(path)

        # remove request from the pending ones, label it as "in progress"
        self.requests_in_progress.add(request_id)
        r.mode = 'waiting'
        r.timestamps['assigned'] = self.time

        # update taxi state in taxi storage
        self.taxis[taxi_id] = t
        # update request state
        self.requests[request_id] = r

        if self.log:
            print("\tM request " + str(request_id) + " taxi " + str(taxi_id))

    def matching_algorithm(self, mode="random_unlimited"):
        """
        This function contains the possible matching functions which are selected by the mode keyword.

        Parameters
        ----------

        mode : str, default baseline
            matching algorithm mode
                * random_unlimited : assigning a random taxi to the user
                * random_limited : assigning a random taxi to the user within the circle of a radius self.city.hard_limit
                * nearest : sending the nearest available taxi for the user from within the circle of a radius self.city.hard_limit
                * poorest : sending the least earning available taxi for the user from within the circle of a radius self.city.hard_limit
        """

        if len(self.requests_pending_deque) == 0:
            if self.log:
                print("No pending requests.")
            return

        if self.log:
            print('Matching algorithm.')

        if mode == "random_unlimited":

            while len(self.requests_pending_deque) > 0 and len(
                    self.taxis_available) > 0:
                # select a random taxi
                taxi_id = self.taxis_available.random_key()
                # select oldest request from deque
                request_id = self.requests_pending_deque.popleft()
                # make assignment
                self.assign_request(request_id, taxi_id)

        elif mode == "random_limited":
            while len(self.requests_pending_deque) > 0 and len(
                    self.taxis_available) > 0:
                # select oldest request from deque
                request_id = self.requests_pending_deque.popleft()
                # fetch request
                r = self.requests[request_id]
                # search for nearest free taxis
                possible_taxi_ids = self.city.find_nearest_available_taxis(
                    self.city.coordinate_dict_ij_to_c[r.ox][r.oy],
                    mode="circle",
                    radius=self.city.hard_limit)
                # if there were any taxis near
                if len(possible_taxi_ids) > 0:
                    # select taxi
                    taxi_id = choice(possible_taxi_ids)
                    self.assign_request(request_id, taxi_id)
                else:
                    # mark request as still pending
                    self.requests_pending_deque_temporary.append(request_id)

        elif mode == "nearest":
            while len(self.requests_pending_deque) > 0 and len(
                    self.taxis_available) > 0:
                # select oldest request from deque
                request_id = self.requests_pending_deque.popleft()
                # fetch request
                r = self.requests[request_id]
                # search for nearest free taxis
                possible_taxi_ids = self.city.find_nearest_available_taxis(
                    self.city.coordinate_dict_ij_to_c[r.ox][r.oy])
                # if there were any taxis near
                if len(possible_taxi_ids) > 0:
                    # select taxi
                    taxi_id = choice(possible_taxi_ids)
                    self.assign_request(request_id, taxi_id)
                else:
                    # mark request as still pending
                    self.requests_pending_deque_temporary.append(request_id)

        elif mode == "poorest":
            # always order taxi that has earned the least money so far
            # but choose only from the nearest ones
            # hard limiting: e.g. if there is no taxi within the radius, then quit

            # evaulate the earnings of the available taxis so far
            ta_list = list(self.taxis_available.keys)
            # print('Available taxis ', self.taxis_available.keys)
            taxi_earnings = [
                self.eval_taxi_income(taxi_id) for taxi_id in ta_list
            ]
            # print('Earnings ', taxi_earnings)
            ta_list = list(np.array(ta_list)[np.argsort(taxi_earnings)])

            pairs = 0
            while len(self.requests_pending_deque) > 0 and len(
                    self.taxis_available) > 0:
                # select oldest request from deque
                request_id = self.requests_pending_deque.popleft()
                # fetch request
                r = self.requests[request_id]
                # find nearest vehicles in a radius
                possible_taxi_ids = self.city.find_nearest_available_taxis(
                    self.city.coordinate_dict_ij_to_c[r.ox][r.oy],
                    mode="circle",
                    radius=self.city.hard_limit)
                hit = 0
                for t in ta_list:
                    if t in possible_taxi_ids:
                        # on first hit
                        # make assignment
                        self.assign_request(request_id, t)
                        hit = 1
                        pairs += 1
                        break
                if not hit:
                    self.requests_pending_deque_temporary.append(request_id)

        else:
            print(
                "I know of no such assignment mode! Please provide a valid one!"
            )

    def pickup_request(self, request_id):
        """
        Pick up passenger.
        
        Parameters
        ----------
        
        request_id : int
        """

        # mark pickup timestamp
        r = self.requests[request_id]
        t = self.taxis[r.taxi_id]

        self.taxis_to_request.remove(r.taxi_id)
        self.taxis_to_destination.add(r.taxi_id)

        # change taxi state to with passenger
        t.to_request = False
        t.with_passenger = True
        t.available = False

        r.timestamps['pickup'] = self.time
        r.mode = 'serving'

        # update request and taxi instances
        self.requests[request_id] = r
        self.taxis[r.taxi_id] = t
        if self.log:
            print('\tP ' + "request " + str(request_id) + ' taxi ' +
                  str(t.taxi_id))

    def dropoff_request(self, request_id, mode="simple"):
        """
        Drop off passenger, when taxi reached request destination.
        
        """

        r = self.requests[request_id]
        t = self.taxis[r.taxi_id]

        if mode == "simple" or mode == "going_home":
            # mark request as done
            r.timestamps['dropoff'] = self.time
            r.mode = 'done'
            self.requests_in_progress.remove(request_id)
            t.requests_completed.add(request_id)
            # remove taxi from to_destination list
            self.taxis_to_destination.remove(r.taxi_id)
        elif mode == "cancel":
            # mark request as dropped
            r.mode = 'dropped'
            # remove request from progressing ones
            self.requests_in_progress.remove(request_id)
            # clear taxi path
            t.next_destination = deque()
            # remove taxi from to_request list
            self.taxis_to_request.remove(r.taxi_id)

        # update taxi lists
        if mode == "going_home":
            # (magic wand) Apparate taxi home!
            t.x, t.y = t.home

        # update global availability containers
        self.taxis_available[r.taxi_id] = t
        self.city.A[self.city.coordinate_dict_ij_to_c[t.x][t.y]].add(r.taxi_id)

        # update taxi internal states
        t.with_passenger = False
        t.available = True
        t.actual_request_executing = None

        # update request and taxi instances in global containers
        self.requests[request_id] = r
        self.taxis[r.taxi_id] = t

        if self.log:
            print("\tD request " + str(request_id) + ' taxi ' + str(t.taxi_id))

    def eval_taxi_income(self, taxi_id):
        """

        Parameters
        ----------
        taxi_id : int
            select taxi from self.taxis with id

        Returns
        -------
        price : int
            evaulated earnnigs of the taxi based on config

        """

        t = self.taxis[taxi_id]

        price =\
            len(t.requests_completed) * self.price_fixed +\
            int(not t.available) * self.price_fixed +\
            t.time_serving*self.price_per_dist -\
            (t.time_cruising+t.time_serving+t.time_to_request)*self.cost_per_unit -\
            (t.time_serving+t.time_cruising+t.time_to_request+t.time_waiting)*self.cost_per_time

        return price

    def plot_simulation(self):
        """
        Draws current state of the simulation on the predefined grid of the class.
        
        Is based on the taxis and requests and their internal states.
        """

        self.init_canvas()

        for taxi_id, i in self.taxis.keys.items():
            t = self.taxis[taxi_id]

            # plot a circle at the place of the taxi
            self.canvas_ax.plot(t.x,
                                t.y,
                                'o',
                                ms=10,
                                c=self.cmap(self.taxi_colors[i]))

            if self.show_map_labels:
                self.canvas_ax.annotate(str(i),
                                        xy=(t.x, t.y),
                                        xytext=(t.x, t.y),
                                        ha='center',
                                        va='center',
                                        color='white')

            # if the taxi has a path ahead of it, plot it
            if len(t.next_destination) > 0:
                path = np.array([[t.x, t.y]] + list(t.next_destination))
                if len(path) > 1:
                    xp, yp = path.T
                    # plot path
                    self.canvas_ax.plot(xp,
                                        yp,
                                        '-',
                                        c=self.cmap(self.taxi_colors[i]))
                    # plot a star at taxi destination
                    self.canvas_ax.plot(path[-1][0],
                                        path[-1][1],
                                        '*',
                                        ms=5,
                                        c=self.cmap(self.taxi_colors[i]))

            # if a taxi serves a request, put request on the map
            request_id = t.actual_request_executing
            if (request_id is not None) and (not t.with_passenger):
                r = self.requests[request_id]
                self.canvas_ax.plot(r.ox, r.oy, 'ro', ms=3)
                if self.show_map_labels:
                    self.canvas_ax.annotate(request_id,
                                            xy=(r.ox, r.oy),
                                            xytext=(r.ox - 0.2, r.oy - 0.2),
                                            ha='center',
                                            va='center')

        # plot taxi base
        self.canvas_ax.plot(self.city.base_coords[0],
                            self.city.base_coords[1],
                            'ks',
                            ms=15)

        # plot pending requests
        if self.show_pending:
            for request_id in self.requests_pending_deque:
                self.canvas_ax.plot(self.requests[request_id].ox,
                                    self.requests[request_id].oy,
                                    'ro',
                                    ms=3,
                                    alpha=0.5)

        self.canvas.show()

    def move_taxi(self, taxi_id):
        """
        Move a taxi one step forward according to its path queue.
        
        Update taxi position on availablity grid, if necessary.
        
        Parameters
        ----------
        plt.ion()
        taxi_id : int
            unique id of taxi that we want to move
        """
        t = self.taxis[taxi_id]

        try:
            # move taxi one step forward
            move = t.next_destination.popleft()

            old_x = t.x
            old_y = t.y

            t.x = move[0]
            t.y = move[1]

            if t.with_passenger:
                t.time_serving += 1
            else:
                if t.available:
                    t.time_cruising += 1
                else:
                    t.time_to_request += 1

            # move available taxis on availability grid
            if t.available:
                self.city.A[self.city.coordinate_dict_ij_to_c[old_x]
                            [old_y]].remove(taxi_id)
                self.city.A[self.city.coordinate_dict_ij_to_c[t.x][t.y]].add(
                    taxi_id)
            if self.log:
                print("\tF moved taxi " + str(taxi_id) + " remaining path ",
                      list(t.next_destination),
                      "\n",
                      end="")
        except:
            t.time_waiting += 1

        self.taxis[taxi_id] = t

    def run_batch(self, run_id, data_path='results'):
        """
        Create a batch run, where metrics are evaluated at every batch step and at the end.
        
        Parameters
        ----------
        
        run_id : str
            id that stands for simulation

        data_path : str
            where to save the results
        """

        # TODO check if data_path exists, if not, throw an error

        measurement = Measurements(self)

        if self.num_iter is None:
            print(
                "No batch run parameters were defined in the config file, please add them!"
            )
            return

        print("Running simulation with run_id " + run_id + ".")
        print("Batch time " + str(self.batch_size) + ".")
        print("Number of items " + str(self.num_iter) + ".")
        print("Total time simulated " + str(self.batch_size * self.num_iter) +
              ".")
        print("Starting...")

        results = []

        time1 = time()
        for i in range(self.num_iter):
            # tick the clock
            for k in range(self.batch_size):
                self.step_time("")

            ptm = measurement.read_per_taxi_metrics()

            if i == 0:
                # clearing future output files
                f = open(
                    data_path + '/run_' + run_id + '_per_taxi_metrics.json',
                    'w')
                f.close()
                f = open(
                    data_path + '/run_' + run_id + '_per_request_metrics.json',
                    'w')
                f.close()

                # adding taxi homes to output
                ptm['taxi_homes'] = [[
                    int(self.taxis[t].home[0]),
                    int(self.taxis[t].home[1])
                ] for t in self.taxis]

            # dumping per taxi metrics out (per batch)
            f = open(data_path + '/run_' + run_id + '_per_taxi_metrics.json',
                     'a')
            json.dump(ptm, f)
            f.write('\n')
            f.close()
            results.append(measurement.read_aggregated_metrics(ptm))
            time2 = time()
            print('Simulation batch ' + str(i + 1) + '/' + str(self.num_iter) +
                  ' , %.2f sec/batch.' % (time2 - time1))

            time1 = time2

        # dumping batch results
        f = open(data_path + '/run_' + run_id + '_aggregates.csv', 'w')
        pd.DataFrame.from_dict(results).to_csv(f, float_format="%.4f")
        f.write('\n')
        f.close()

        # dumping per request metrics out (only at the end)
        f = open(data_path + '/run_' + run_id + '_per_request_metrics.json',
                 'a')
        prm = measurement.read_per_request_metrics()
        json.dump(prm, f)
        f.write('\n')
        f.close()

        # compressing written objects
        for file in [
                '_per_taxi_metrics.json', '_per_request_metrics.json',
                '_aggregates.csv'
        ]:
            f1 = open(data_path + '/run_' + run_id + file, 'rb')
            f2 = gzip.open(data_path + '/run_' + run_id + file + '.gz', 'wb')
            shutil.copyfileobj(f1, f2)
            f1.close()
            f2.close()
            os.remove(data_path + '/run_' + run_id + file)

        print("Done.\n")

    def step_time(self, handler):
        """
        Ticks simulation time by 1.
        """

        if self.log:
            print("\n")
            print("Timestamp " + str(self.time))
            print("Taxis:\n")
            print("\t Available: " + str(len(self.taxis_available)))
            print("\t To request: " + str(len(self.taxis_to_request)))
            print("\t To destination: " + str(len(self.taxis_to_destination)))
            print("\n")
            req_counter = {'TOTAL': self.latest_request_id}
            for request_id in self.requests:
                r = self.requests[request_id]
                if r.mode in req_counter:
                    req_counter[r.mode] += 1
                else:
                    req_counter[r.mode] = 1
            print('Requests:')
            for mode in req_counter:
                print('\t' + mode + ': ' + str(req_counter[mode]))
            print("\n")
            print("Requests pending: ")
            print(self.requests_pending)
            print(self.requests_pending_deque)
            print(self.requests_pending_deque_temporary)

        if (self.time > 0) and (self.time % self.reset_time == 0):
            # print("Going home!")
            self.go_home_everybody()
        else:
            # move every taxi one step towards its destination
            for taxi_id in self.taxis:
                self.move_taxi(taxi_id)

                t = self.taxis[taxi_id]

                # if a taxi can pick up its passenger, do it
                if taxi_id in self.taxis_to_request:
                    r = self.requests[t.actual_request_executing]
                    if (t.x == r.ox) and (t.y == r.oy):
                        try:
                            self.pickup_request(t.actual_request_executing)
                        except KeyError:
                            print(t)
                            print(r)
                # if a taxi can drop off its passenger, do it
                elif taxi_id in self.taxis_to_destination:
                    r = self.requests[t.actual_request_executing]
                    if (t.x == r.dx) and (t.y == r.dy):
                        self.dropoff_request(r.request_id)
                        if self.behaviour == "go_back":
                            if self.initial_conditions == "base":
                                self.go_to_base(taxi_id, self.city.base_coords)
                            elif self.initial_conditions == "home":
                                self.go_to_base(taxi_id, t.home)
                        elif self.behaviour == "stay":
                            pass
                        elif self.behaviour == "cruise":
                            self.cruise(taxi_id)
        # make matchings
        self.matching_algorithm(mode=self.matching)

        # reunite pending requests
        self.requests_pending_deque_temporary.reverse()
        self.requests_pending_deque.extendleft(
            self.requests_pending_deque_temporary)
        self.requests_pending_deque_temporary = deque()
        # delete old requests from pending ones
        if self.time > self.max_request_waiting_time and len(
                self.requests_pending_deque) > 0:
            while len(self.requests_pending_deque) > 0 and (
                    self.requests_pending_deque[0]
                    in self.requests_pending_deque_batch[0]):
                request_id = self.requests_pending_deque.popleft()
                self.requests[request_id].mode = 'dropped'

        self.requests_pending = set(self.requests_pending_deque)

        # generate requests
        new_requests = set()
        rfrac, rint = np.modf(self.request_rate)
        for i in range(int(rint)):
            self.add_request()
            new_requests.add(self.latest_request_id)
        if rfrac > 1e-3:
            try:
                p = self.city.request_p.pop()
            except IndexError:
                self.city.request_p.extend(np.random.random(self.city.length))
                p = self.city.request_p.pop()
            if p < rfrac:
                self.add_request()
                new_requests.add(self.latest_request_id)

        # this automatically pushes out requests that have been waiting for too long
        self.requests_pending_deque_batch.append(new_requests)

        if self.show_plot:
            self.plot_simulation()

        # step time
        self.time += 1
Пример #5
0
def test_empty_random_key():
    r = RandomDict()
    r.random_key()
Пример #6
0
class Model():
    def __init__(self, gui, num_agents):
        self.GUI = gui
        self.initial_population = num_agents
        self.total_agents_created = 0
        self.goods_params = {
            "sugar": {
                "min": 5,
                "max": 25
            },
            "water": {
                "min": 5,
                "max": 25
            }
        }

        self.max_vision = 1
        # hash table that identifies possible moves relative to agent position
        self.move_dict = {
            v: {
                i:
                {j: True
                 for j in range(-v, v + 1) if (i**2 + j**2) <= (v**2)}
                for i in range(-v, v + 1)
            }
            for v in range(1, self.max_vision + 1)
        }

        #sugarMap.shape calls the a tuple with dimensions
        #of the dataframe
        self.sugarMap = pd.read_csv('sugar-map.txt', header=None, sep=' ')
        # add 1 to each max_Val
        for key in self.sugarMap:
            self.sugarMap[key] = self.sugarMap[key].add(1)
        self.rows, self.cols = self.sugarMap.shape
        #Use to efficiently track which patches are empty
        self.initializePatches()
        self.initializeAgents()
        # self.aggregate_data = {"agent":}

    def initializePatches(self):
        #Instantiate Patches
        #Create a list to hold the patches. We first fill these with
        #zeros to hold the place for each Patch object
        self.patch_dict = {
            i: {
                j: 0
            }
            for i in range(self.rows) for j in range(self.cols)
        }
        for i in range(self.rows):
            for j in range(self.cols):
                #replace zeros with actual Patch objects
                good = "sugar" if i + j >= self.rows else "water"
                self.patch_dict[i][j] = Patch(self, i, j, self.sugarMap[i][j],
                                              good)
        self.empty_patches = RandomDict({(i, j): self.patch_dict[i][j]
                                         for i in range(self.rows)
                                         for j in range(self.cols)})

    def initializeAgents(self):
        self.agent_dict = {}
        # self.agentLocationDict = {}
        for i in range(self.initial_population):
            self.total_agents_created += 1
            ID = self.total_agents_created
            row, col = self.chooseRandomEmptyPatch()
            del self.empty_patches[row, col]
            self.agent_dict[ID] = Agent(self, row, col, ID)

#     def recordAgentLocationInDict(self, agent):
#         patchIndex = self.convert2dTo1d(agent.row, agent.col)
#         self.agentLocationDict[patchIndex] = agent

    def chooseRandomEmptyPatch(self):
        i, j = self.empty_patches.random_key()
        return i, j

    def runModel(self, periods):
        agent_list = list(self.agent_dict.values())
        for period in range(1, periods + 1):
            # print("period:", period)
            self.growPatches()
            random.shuffle(agent_list)
            for agent in agent_list:
                self.agentMove(agent)
            if self.GUI.live_visual:
                if period % self.GUI.every_t_frames == 0:
                    self.GUI.updatePatches()
                    self.GUI.moveAgents()
                    self.GUI.canvas.update()

    def agentMove(self, agent):
        # save agent coords to track agent movement, changes in (not) empty patches
        curr_i, curr_j = agent.row, agent.col
        max_patch, near_empty_patch = self.findMaxEmptyPatch(
            agent, curr_i, curr_j)
        if near_empty_patch[agent.target]:
            target = agent.target
        else:
            target = agent.not_target
        self.moveToMaxEmptyPatch(agent, curr_i, curr_j, max_patch,
                                 near_empty_patch, target)
        self.agentHarvest(agent)

    def findMaxEmptyPatch(self, agent, curr_i, curr_j):
        # dict to save empty patch with max q for each good
        max_patch = {
            good: {
                "Q": 0,
                "patch": None
            }
            for good in self.goods_params
        }

        patch_moves = [(curr_i + i, curr_j + j)
                       for i in self.move_dict[agent.vision]
                       for j in self.move_dict[agent.vision][i]]
        # shuffle patches so not movement biased in one direction
        random.shuffle(patch_moves)
        near_empty_patch = {good: False for good in self.goods_params}
        for coords in patch_moves:
            if coords in self.empty_patches:
                i, j = coords[0], coords[1]
                empty_patch = self.patch_dict[i][j]
                patch_q = empty_patch.Q
                patch_good = empty_patch.good
                near_empty_patch[patch_good] = True
                if patch_q > max_patch[patch_good]["Q"]:
                    max_patch[patch_good]["patch"] = empty_patch
                    max_patch[patch_good]["Q"] = patch_q
        return max_patch, near_empty_patch

    def moveToMaxEmptyPatch(self, agent, curr_i, curr_j, max_patch,
                            near_empty_patch, target):
        if near_empty_patch[target]:
            # agent_move()
            target_patch = max_patch[target]["patch"]
            new_coords = target_patch.row, target_patch.col
            agent.dx = target_patch.col - curr_j
            agent.dy = target_patch.row - curr_i
            agent.row, agent.col = new_coords
            del self.empty_patches[new_coords]
            self.empty_patches[curr_i,
                               curr_j] = self.patch_dict[curr_i][curr_j]
        else:
            agent.dx = 0
            agent.dy = 0

    def agentHarvest(self, agent):
        agent_patch = self.patch_dict[agent.row][agent.col]
        agent.good[agent_patch.good] += agent_patch.Q
        agent_patch.Q = 0

    def growPatches(self):
        for i, vals in self.patch_dict.items():
            for patch in vals.values():
                if patch.Q < patch.maxQ:
                    patch.Q += 1
Пример #7
0
def genquery(genomeFile, jellyFile, totedits, medindel, insprob, delprob, queryfreq, querycount,  outputFile):
    #genome - path to genome
    #totedits - total number of edits to make
    #medindel - median (mean) size of indel edits. actual edit length determined from gaussian with mean medindel and std medindel/2
    #insprob - probability of insertion
    #delprob - probability of deletion
    #outputs all edits into a text file called "sampleedits.txt"

    if delprob + insprob > 1.0:
        raise "Error, delprob = {} and insprob = {}. "\
              "The sum is {} > 1.0".format(
                delprob, insprob, delprob + insprob)

    genome = genomeFile.readline()
    genomeFile.close()
    #mf = jellyfish.ReadMerFile(jellyFile)
    qf = jellyfish.QueryMerFile(jellyFile)
    numbases = len(genome)-1
    genome = genome[0:numbases]
    letters = ['A','C','G','T']
    randr = []
    allinds = []
    snpProb = 1.0 - (insprob + delprob)
    SNPrange = int(snpProb * totedits)
    insrange = int(insprob * totedits)
    delrange = int(delprob * totedits)

    editTypes = (['S'] * SNPrange) +\
                (['D'] * delrange) +\
                (['I'] * insrange)

    random.shuffle(editTypes)
    qcount = 0
    #effectedkmers = dict()
    effectedkmers =  RandomDict()
    count=0
    sample=10
    for val in editTypes:
        qcount += 1
        if val == 'I':
            p, s, seq = random_insertion(numbases, medindel)
            numbases += s
            outputFile.write('I %d %s\n' % (p, seq))
            if ((qcount-1)%sample)==0:
                add_kmers_in_seq(effectedkmers, seq)
                add_kmers_in_seq(effectedkmers, genome[p-K+1:p+K])

        elif val == 'D':
            p, s = random_deletion(numbases, medindel)
            numbases -= s
            outputFile.write('D %d %d\n' % (p, p+s-1))
            #add_kmers_in_seq(effectedkmers, genome[p-K+1:p+s-1+K])

        else:
            p, seq = random_snp(numbases)
            outputFile.write('S %d %s\n' % (p, seq))

            if ((qcount-1)%sample)==0:
                add_kmers_in_seq(effectedkmers, genome[p-K+1:p+K-1])

        # if it's time to output some queries
        if qcount == queryfreq:
            qcount = 0
            for qlist in xrange(querycount):
                dart = random.random()
                if dart <= EDIT_QUERY_PROB:
                    kmer = effectedkmers.random_key()
		    #kmer = random.choice(effectedkmers.keys())
		    #kmer = random.sample(effectedkmers, 1)[0]
                    editflag = 'I'
                else:
                    p = random.randrange(K*2, numbases - K*2)
                    kmer = genome[p:p+K].upper()
                    editflag = 'N'
                
		kcount = 0
                #kcount = int(qf[jellyfish.MerDNA(kmer)])
                outputFile.write('Q %s %s %d\n' % (kmer, editflag, kcount))
    
    outputFile.close()
Пример #8
0
class Model():
    def __init__(self, gui, num_agents, mutate, genetic, live_visual,
                 agent_attributes, model_attributes):
        if live_visual:
            self.GUI = gui
        self.live_visual = live_visual
        self.name = gui.name
        self.run = gui.run
        self.initial_population = num_agents
        self.mutate = mutate
        self.genetic = genetic
        self.agent_attributes = agent_attributes
        self.model_attributes = model_attributes
        self.attributes = agent_attributes + model_attributes
        # attributes that are not copied during mutation or herding
        self.drop_attr = [
            "col", "row", "dx", "dy", "id", "wealth", "top_wealth", "sugar",
            "water", "target", "not_target", "exchange_target",
            "not_exchange_target", "parent", "image"
        ]
        # if self.GUI.live_visual:
        #     self.drop_attr.append("image")
        if self.mutate:
            self.max_mutate_rate = 0.5 if mutate else 0  #.5
        if self.genetic:
            self.cross_over_rate = .5
        ############    set model parameters    ############
        self.total_agents_created = 0
        self.goods = ["sugar", "water"]
        self.goods_params = {
            good: {
                "min": 5,
                "max": 25
            }
            for good in self.goods
        }

        self.max_init_demand_vals = {
            "price": {
                "min": 1 / 2,
                "max": 2
            },
            "quantity": {
                "min": 10,
                "max": 25
            }
        }
        self.consumption_rate = {"sugar": .5, "water": .5}
        self.primary_breeds = ["basic", "switcher", "arbitrageur"]
        self.secondary_breeds = ["herder"]

        self.breeds = self.primary_breeds + self.secondary_breeds
        # all agents start as basic, only mutation can create other agents
        basic = 1
        self.breed_probabilities = {
            "basic": basic,  # if you are not a basic, you are a switcher
            "herder": 0,
            "arbitrageur": 0
        }
        self.max_vision = 1
        # record price of every transaction
        # then take average at end of period
        self.transaction_prices = []
        self.average_price = np.nan
        self.total_exchanges = 0
        ############ import map and build nav_dict ############
        # hash table that identifies possible moves relative to agent position
        self.nav_dict = {
            v: {
                i: {
                    j: True
                    for j in range(-v, v + 1) if 0 < (i**2 + j**2) <= (v**2)
                }
                for i in range(-v, v + 1)
            }
            for v in range(1, self.max_vision + 1)
        }
        #sugarMap.shape calls the a tuple with dimensions
        #of the dataframe
        self.sugarMap = pd.read_csv('sugar-map.txt', header=None, sep=' ')
        # add 1 to each max_Val
        for key in self.sugarMap:
            self.sugarMap[key] = self.sugarMap[key].add(1)
        self.rows, self.cols = self.sugarMap.shape

        ############   Initialization   ############
        self.initializePatches()
        self.initializeAgents()
        self.data_dict = shelve.open("shelves\\masterShelve", writeback=True)
        for attribute in self.attributes:
            self.data_dict[attribute] = shelve.open("shelves\\subshelve-" +
                                                    attribute,
                                                    writeback=True)

    def initializePatches(self):
        #Instantiate Patches
        #Create a dictionary to hold the patches, organize as grid.
        #We first fill these with zeros as placeh holders
        self.patch_dict = {
            row: {
                col: 0
            }
            for row in range(self.rows) for col in range(self.cols)
        }
        for row in range(self.rows):
            for col in range(self.cols):
                # replace zeros with actual Patch objects
                good = "sugar" if row + col < self.cols else "water"
                self.patch_dict[row][col] = Patch(self, row, col,
                                                  self.sugarMap[row][col],
                                                  good)

    # use RandomDict - O(n) time complexity - for choosing random empty patch
        self.empty_patches = RandomDict({(row, col): self.patch_dict[row][col]
                                         for row in range(self.rows)
                                         for col in range(self.cols)})

    def initializeAgents(self):
        # agents stored in a dict by ID
        self.agent_dict = {
        }  #if self.live_visual else Chest(path = data_aggregator.folder) #shelve.open("agent_dict")
        # dead agents will be removed from agent_dict
        for i in range(self.initial_population):
            self.total_agents_created += 1
            ID = self.total_agents_created
            row, col = self.chooseRandomEmptyPatch()
            self.agent_dict[ID] = Agent(self, row, col, ID)
            self.patch_dict[row][col].agent = self.agent_dict[ID]
        self.population = self.total_agents_created
#     def recordAgentLocationInDict(self, agent):
#         patchIndex = self.convert2dTo1d(agent.row, agent.col)
#         self.agentLocationDict[patchIndex] = agent

    def chooseRandomEmptyPatch(self):
        row, col = self.empty_patches.random_key()
        del self.empty_patches[row, col]

        return row, col

    def runModel(self, periods):
        def updateModelVariables():
            self.population = len(agent_list)
            self.average_price = gmean(self.transaction_prices)
            self.transaction_prices = []

        for period in range(1, periods + 1):
            self.growPatches()
            agent_list = list(self.agent_dict.values())
            random.shuffle(agent_list)
            for agent in agent_list:
                agent.move()
                agent.harvest()
                agent.trade()
                agent.consume()
                agent.checkAlive()
                agent.reproduce()
                agent.updateParams()

            # data_aggregator.collectData(self, self.name,
            #                                  self.run, period)
            updateModelVariables()
            self.collectData(str(period))

            if self.live_visual:
                if period % self.GUI.every_t_frames == 0:
                    print("period",
                          period,
                          "population",
                          self.population,
                          sep="\t")
                    self.GUI.parent.title("Sugarscape: " + str(period))
                    self.GUI.updatePatches()
                    self.GUI.moveAgents()
                    self.GUI.canvas.update()

            if period == periods:
                mem_usage = memory_usage(-1, interval=1)  #, timeout=1)
                print(period,
                      "end memory usage before sync//collect:",
                      mem_usage[0],
                      sep="\t")
                self.data_dict.sync()
                gc.collect()
                mem_usage = memory_usage(-1, interval=1)  #, timeout=1)
                print(period,
                      "end memory usage after sync//collect:",
                      mem_usage[0],
                      sep="\t")

    def growPatches(self):
        for i in self.patch_dict:
            for patch in self.patch_dict[i].values():
                if patch.Q < patch.maxQ:
                    patch.Q += 1

    def collectData(self, period):
        def collectAgentAttributes():
            temp_dict = {}
            for attribute in self.agent_attributes:
                temp_dict[attribute] = []
            for ID, agent in self.agent_dict.items():
                for attribute in self.agent_attributes:
                    temp_dict[attribute].append(getattr(agent, attribute))

            for attribute, val in temp_dict.items():
                self.data_dict[attribute][period] = np.mean(val)

        def collectModelAttributes():
            for attribute in self.model_attributes:
                self.data_dict[attribute][period] = getattr(self, attribute)

        collectAgentAttributes()
        collectModelAttributes()