def intersection_tick(self, streets):
        # todo (cleanup): make function similar to functional programming
        # if this is the first tick
        if self.cycle_position == -1:
            self.cycle_position += 1
            streets[cl.find(
                streets, self.schedule.iat[self.cycle_position])].flip_state()
            return streets

        previous_position = self.schedule.iat[self.cycle_position]
        # increment current cycle position
        if self.cycle_position + 1 == len(self.schedule):
            # Reset the timer to 1 if it reached the end
            self.cycle_position = 0
        else:
            self.cycle_position += 1
        # print(self.cycle_position)
        current_position = self.schedule.iat[self.cycle_position]

        # Check if lights need to change
        if previous_position != current_position:
            # Turn off previous position and turn on current position
            streets[cl.find(streets, previous_position)].flip_state()
            streets[cl.find(streets, current_position)].flip_state()

        return streets
예제 #2
0
    def move_queue(self, street):
        """
        Helper function
        :param street:
        :return:
        """
        # pop the first member of the queue and have it cross the street
        car = self.cars[cl.find(self.cars, street.pop_queue())]
        car.cross_intersection()

        # Add the car to its new street
        self.streets[cl.find(
            self.streets, car.get_current_streetID)].place_car_in_traffic(car)
예제 #3
0
 def print_lights(cls, tick, intersections, streets):
     print("tick: " + str(tick))
     for i in intersections:
         print("\tintersection: " + str(i.get_id))
         for s in i.get_streets:
             print("\t\t" + s + ": " +
                   streets[cl.find(streets, s)].get_state)
예제 #4
0
    def optimize_lights(cls, intersections, streets):
        """
        run_simulation helper function
        :return:
        """
        # Find lights that are always set to on/off and mark as such to optimize later ticks
        remove_list = []
        for i in intersections:
            # A light is always on if only one light is mentioned in a schedule
            if i.get_schedule is None:
                # print("Removing intersection " + str(i.get_id) + " because its always red.")
                remove_list.append(i.get_id)

            # A light is always off if the intersection is not listed in the schedule
            elif i.get_schedule.unique().size == 1:
                # Street to update
                streets[cl.find(streets, i.get_schedule[0])].flip_state()
                # print("Removing intersection " + str(i.get_id) + " because its always green.")

                # Remove light from list of intersections to check each tick
                remove_list.append(i.get_id)
        # Remove intersections scheduled for disposal
        intersections = [
            r for r in intersections if r.get_id not in remove_list
        ]

        return intersections, streets
예제 #5
0
    def cut_streets(cls, cars, streets, intersections):
        # Create list of all streets and intersections cars touch
        all_streets = pd.DataFrame()

        # todo (optimization): optimize
        for i in cars:
            all_street = pd.DataFrame()
            all_street['streets'] = i.get_path

            # grab the intersection ids
            all_street['intersections'] = [
                streets[cl.find(streets, j)].get_intersection
                for j in i.get_path
            ]
            all_streets = all_streets.append(all_street)

        # Convert list into pandas series of unique streets
        unique_streets = all_streets['streets'].unique()
        unique_intersections = all_streets['intersections'].unique()

        # Delete all streets not in unique_streets
        # Gather list of streets not in unique_streets
        streets = [
            street for street in streets if street.get_id in unique_streets
        ]

        # Delete all intersections not in unique_intersections
        # Gather list of intersections not in unique_intersections
        intersections = [
            it for it in intersections
            if str(it.get_id) in unique_intersections
        ]

        return streets, intersections
예제 #6
0
    def add_delay(self, cars, tick):
        # Count number of cars in queue array and add 1 delay for each
        new_row = {
            'tick': tick,
            'cars': self.queue,
            'delay added': len(self.queue)
        }
        self.street_delay_df.append(new_row)

        for i in self.queue:
            cars[cl.find(cars, i)].add_delay(tick)
예제 #7
0
    def read_input(cls, file):
        # Read in the first line, which contains the simulation-wide variables
        f = open(file, 'r')
        line = f.readline().split(' ')

        # Instantiate the Simulation class
        # todo: add documentation on which line part is what
        sim = Simulation(int(line[0]), int(line[1]), int(line[2]),
                         int(line[3]), int(line[4]))

        # Create the streets
        streets = []
        intersections = []
        for x in range(sim.get_num_streets):
            line = f.readline().split(' ')
            streets.append(Street.Street(line[2], line[0], line[1], line[3]))

            # Add the new intersection to the list, or add new street to existing intersection
            # Check if current intersection is already in the list
            # todo: rewrite code to look/add new intersections in both line[0] and line[1]
            i = cl.find(intersections, int(line[1]))
            if i > -1:
                # Check if current street is already in the intersection's list
                if line[2] not in intersections[i].get_streets:
                    intersections[i].add_street(line[2])
            else:
                # Add new intersection
                intersections.append(
                    Intersection.Intersection(line[1], line[2]))

        # Store streets and intersections in the simulation
        # todo: add check to see if num streets found = self.num_streets
        sim.set_streets(streets)

        # todo: add check to see if number of intersections found = self.num_intersections
        sim.set_intersections(intersections)

        # Create the cars
        cars = []
        for y in range(sim.get_num_cars):
            line = f.readline().replace('\n', '').split(
                ' '
            )  # Need to remove new line character to avoid bug when finding unique streets
            # todo: add security check that line[0] doesn't exceed the number of streets aka line[1:]
            cars.append(Car.Car(y + 1, line[1:]))

        # store cars in the simulation's car array
        sim.set_cars(cars)

        # Close the file
        f.close()
        return sim
예제 #8
0
 def move_traffic(self, street):
     """
     Helper function
     :param street:
     :return:
     """
     traffic_areas = street.has_traffic
     if traffic_areas[0] != -1:
         if traffic_areas[0] == 0:
             # Check if the car(s) reached their final destination
             # todo (clean code): move this block of code into a helper function
             for car in street.get_traffic_cars(0):
                 if self.cars[cl.find(
                         self.cars, car)].get_destination == street.get_id:
                     self.score_car(car)
                 else:
                     # Add car to queue
                     street.place_car_in_queue(car)
         # Update the rest of the traffic
         street.tick_traffic()
    def add_delay(self, streets, tick):
        """
        Call this function after calculating delay for the streets first
        :param tick: Current tick
        :param streets: list of streets from Simulation for Intersection to query
        """
        new_row = {'tick': tick}
        # todo: (optimize) find more dynamic way to calculate total_delay
        total_delay = 0

        for i in range(4):
            new_row['street ' + str(i + 1)] = self.streets[i]
            current_column = 's' + str(i + 1) + ' delay'
            new_row[current_column] = streets[cl.find(
                streets, self.streets[i])].get_current_delay()
            total_delay += new_row[current_column]

        # Get total delay
        new_row['total delay'] = total_delay

        # Add new row to the dataframe
        self.intersection_delay_df.append(new_row, ignore_index=True)
예제 #10
0
    def read_submission(self, file):
        f = open(file, 'r')
        num_schedules = int(f.readline())

        # Read through the file as specified by the first line
        for x in range(num_schedules):
            # This line tell us the intersection we're working with

            intersection = int(f.readline())
            # print("Working on intersection " + intersection)
            # The next line tells us how many lights we're looking at
            num_lights = int(f.readline())

            schedules = []

            # need to be able to reference the streets based on the intersection id
            for y in range(num_lights):
                # Grab the line
                line = f.readline().split(' ')

                # todo: add documentation describing what line parts are what
                # schedule['street'] = line[0]
                # todo: add timer variable constraints (1 <= timer <= duration)
                for i in range(int(line[1])):
                    schedules.append(line[0])

            # Give the schedule to the appropriate intersection
            # todo: add try-except statement in case unable to find intersection for whatever reason
            self.intersections[cl.find(self.intersections,
                                       intersection)].set_schedule(
                                           pd.Series(schedules))
            # print(intersection)

        #  Finally, cut all unnecessary streets and intersections, where no car will interact with them
        self.streets, self.intersections = self.cut_streets(
            self.cars, self.streets, self.intersections)