def view_package_bundle(text, bundle, time):
        h, m, s = time
        now = datetime.datetime.now()

        # Truck IDs are indicated by the first parameter in the Truck object, and their leaving time
        # has been pre-calculated to fit the constraints of the project. check_time is derived from
        # user input to stop a Truck during the greedy algorithm comparisons.
        check_time = now.replace(hour=h, minute=m, second=s)
        ds.package_delivery(Truck(1, now.replace(hour=8, minute=0, second=0)),
                            first_bundle, check_time)
        ds.package_delivery(Truck(2, now.replace(hour=9, minute=5, second=0)),
                            second_bundle, check_time)
        ds.package_delivery(Truck(3, now.replace(hour=10, minute=0, second=0)),
                            third_bundle, check_time)

        # Prints package information
        print("\n\t▪■▪", text, check_time.strftime("%H:%M:%S"), "▪■▪")
        print("{:<5}{:<41}{:<19}{:<8}{:<8}{:<11}{:<8}{:<19}{}".format(
            "ID", "Address", "City", "State", "Zip", "Deadline", "Kilos",
            "Status", "Note"))
        for id_ in bundle:
            package = ds.package_hash_table.search_package_by_id(id_)
            print(package)
            # Resets package status to default
            package.status = Package.AT_FACILITY
        print()
Example #2
0
 def test_get_next_product_id(self):
     truck = Truck([5, 7, 0, 3], [3, 2, 4, 1])
     expected = [3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
     for expect in expected:
         product_id = truck.get_next_product_id()
         self.assertEqual(product_id, expect)
         truck.pop_product()
 def load_truck_with_packages(self, truck: Truck, packages: List[Package],
                              time: datetime) -> Truck:
     if truck.can_load(len(packages)):
         for package in packages:
             self.update_package_status(package, PackageStatus.ON_TRUCK,
                                        time)
             truck.load_package(package)
     return truck
Example #4
0
 def return_to_hub(truck: Truck):
     #Returns truck to HUB. Trucks status is updated. Current destination is set to HUB's location ID. Distance to next
     #delivery is set to weight between current location and HUB.
     del_str = "Returning to HUB "
     print(truckUpdate + del_str)
     truck.current_destination = HUB
     update_delivery_status(truck)
     if(len(truck.package_list) > 0):
         the_hash.update_pkg(truck.package_list[0])
         truck.distance_to_next_delivery = the_graph.return_weight_with_id(truck.package_list.pop(0).location_id, 0)
Example #5
0
def sort_packages(the_truck: Truck):  

    #Sort function begins by sorting all packages with early delivery
    #to the front of the package_list using a bubble sort. The next step
    #is to group any packages with the same destination. The final step is
    #to bubble sort all packages, starting with the first EOD delivery, based
    #on nearest neighbor.
   

    def sort_for_early_delivery(package_list):

    #Bubblesort the package_list to sort by deadline. If iterate through list and compare
    #based on deadline. If deadline is less move towards the front of the list.

        index_of_last_nonEOD = 0
        for i in range(len(package_list)):
            if(package_list[i].deadline != "EOD"):
                index_of_last_nonEOD = i
            for j in range(len(package_list)-i - 1):
                    if(package_list[j].getDeadline() > package_list[j+1].getDeadline()):
                        later_pkg = package_list[j]
                        package_list[j] = package_list[j+1]
                        package_list[j+1] = later_pkg
        return index_of_last_nonEOD

    def sort_for_duplicate_locations(package_list):

    #Iterate through package_list and group all packages
    #with the same location_id

        for i in range(len(package_list)):
            for j in range(i+2, len(package_list)):
                if package_list[i].location_id == package_list[j].location_id:
                    temp = package_list[j]
                    package_list.remove(temp)
                    package_list.insert(i, temp)
        return 0

    #Use bubble sort to arrange packages by nearest neighbor.
    #Packages are already sorted by deadline. Start with final non-EOD
    #package and then find nearest neighbor by comparing the returned value
    #from the return_weight_with_id function.

    start = sort_for_early_delivery(the_truck.package_list)
    sort_for_duplicate_locations(the_truck.package_list)

    for i in range(start,len(the_truck.package_list)):
        for j in range(i, len(the_truck.package_list) - i - 1):
            if the_graph.return_weight_with_id(i, j) > the_graph.return_weight_with_id(i, j+1):
                temp = the_truck.package_list[j]
                the_truck.package_list[j] = the_truck.package_list[j + 1]
                the_truck.package_list[j + 1] = temp

    return 0
Example #6
0
    def __init__(self):
        self._trucks = []

        truck = Truck(1)
        self._trucks.append(truck)

        # holding this truck at the hub until delayed packages arrive
        truck = Truck(2)
        truck.clock = datetime.now().replace(hour=9,
                                             minute=5,
                                             second=0,
                                             microsecond=0)
        self._trucks.append(truck)
Example #7
0
    def getBestPlan(trunk: Truck, orders: List[Order]):
        actions = []
        for order in orders:
            action = Action(order)
            order.setAction(action)
            actions.append(action)

        plan_1 = Plan(len(actions), actions)
        plan_2 = Plan(len(actions), actions)
        plan_3 = Plan(len(actions), actions)

        best_plan = Plan.getBestOfPlans(plan_1, plan_2, plan_3)

        trunk.setPlan(best_plan)
        return best_plan
Example #8
0
    def initialize(self):
        self.status = 'INIT'
        ## all cities
        self.cities = City.load()

        ## opend cities
        self.accessible_cities = self.cities
        for city in self.cities:
            city.add_cargos(Cargo.generate(city, self.cities, 5))

        ## owned trucks
        self.trucks = Truck.load()

        self.cur_city = self.cities[0]
        self.cur_truck = None
        self._map = Map(self.cities)

        fm_map = MapForm(self)
        fm_trucks = TruckList(self, [])
        fm_menu = Menu(self)
        fm_city = CityForm(self)
        fm_cargo = CargoList(self, [])
        fm_wild = WildForm(self)

        self.forms.append(fm_map)
        self.forms.append(fm_trucks)
        self.forms.append(fm_menu)
        self.forms.append(fm_city)
        self.forms.append(fm_cargo)
        self.forms.append(fm_wild)

        self.cur_form = 3
        self.focus = self.forms[self.cur_form].focus()

        self.refresh_truck()
Example #9
0
 def __init__(self, timeLimit, ID, code, startLocation, destination,
              latitude, longitude):
     self.truck = Truck(ID, code, startLocation, destination, latitude,
                        longitude)
     self.timeLimit = timeLimit
     self.setRoute()
     self.GUI = GUI()
def animate(problem, filename, num_trucks):
    with open(path + filename + ".txt") as f:
        customers = import_customers(problem + ".txt", False)
        Distances.calculate_matrix(customers)
        lines = f.readlines()

        ids = []
        for line in lines[5:]:
            ids.append(line.split()[3:])

    routes = []
    for line in ids:
        route = []
        for cust_number in line:
            route.append((customers[int(cust_number) - 1]))
        routes.append(route)

    truck_lists = []
    for i in range(len(routes)):
        if i % num_trucks == 0:
            truck_lists.append([])
        truck_lists[-1].append(
            Truck(i % num_trucks, 0, 0, len(routes), Path(routes[i])))

    for trucks in truck_lists:
        State(trucks).plot()
        time.sleep(.3)
Example #11
0
    def multiple_pkgs_same_address(truck: Truck):
        #Handles multiple deliveries to same address. While all_pkgs remains false, the first package of the list
        #will be delivered. If the package_list is empy, the truck will return to HUB. Otherwise the next package 
        #will be checked. If next package is to same destination the loop will continue, if not the truck will continue
        #to the next destination.

        all_pkgs = False
        while(all_pkgs == False):
            del_str = "\tPackage #%s Delivered " % (truck.package_list[0].ID)
            print(del_str)
            update_delivery_status(truck)
            the_hash.update_pkg(truck.package_list[0])
            current_delivery = truck.package_list.pop(0).location_id

            if(len(truck.package_list) == 0):
                all_pkgs = True
                return_to_hub(truck)
            else:
                next_delivery = truck.package_list[0].location_id
                truck.distance_to_next_delivery = the_graph.return_weight_with_id(current_delivery, next_delivery)
                if(truck.distance_to_next_delivery > 0 and all_pkgs == False):
                    truck.distance_to_next_delivery += miles_over_destination
                    all_pkgs = True
                    del_str = "Next Stop: %-39s %-18s |Package Number: %-2s |Distance: %.1f " % (truck.package_list[0].address, truck.package_list[0].city, truck.package_list[0].ID, truck.distance_to_next_delivery)
                    print(truckUpdate + del_str)
        return 0
Example #12
0
 def __init__(self, number_of_storage: int, truck: Truck,
              storage: List[Storage]):
     self._truck = truck
     self._storage = storage
     self.N = number_of_storage
     self._plans = [truck.bestAction(storage[0])]
     for i in range(len(storage) - 1):
         self._plans.append(storage[i].bestAction(storage[1 + 1]))
Example #13
0
 def add_object(self):
     vehicleType = random.randint(0,2)
     if vehicleType == self.CAR:
         Object = Car(self.display,int(self.width/10),self.height,0,0,self.Hspeed,self.direction)
     elif vehicleType == self.TRUCK:
         Object = Truck(self.display,int(self.width/5),self.height,0,0,self.Hspeed,self.direction)
     else:
         Object = Bike(self.display,int(self.width/10),self.height,0,0,self.Hspeed,self.direction)
     return Object
Example #14
0
def initial_state(problem, filename):
    global customers

    if filename == "nearest_neighbors":
        print "Generating nearest neighbors solution..."
        depot_c = Customer(0, 0, 0, 0, 0, 0, 0)
        c = [depot_c]
        for cust in customers:
            c.append(cust)

        paths = Dijsktra.get_nearest_neighbors_all_trucks(c, depot_c, num_trucks)

        trucks = []
        for k in range(1, num_trucks + 1):
            t = Truck(k, 0, 0, truck_capacity, path = Path(paths[k-1][1:]))
            trucks.append(t)

        state = State( trucks, parent = None )
    
    elif filename == "nn_random":
        print "Generating nearest neighbors random solution..."
        depot_c = Customer(0, 0, 0, 0, 0, 0, 0)
        c = [depot_c]
        for cust in customers:
            c.append(cust)

        paths = Dijsktra.get_nearest_neighbors_random(c, depot_c, num_trucks, 2)

        trucks = []
        for k in range(1, num_trucks + 1):
            t = Truck(k, 0, 0, truck_capacity, path = Path(paths[k-1][1:]))
            trucks.append(t)

        state = State( trucks, parent = None )
        state.plot()

    else:
        state = import_solution(problem, filename)

    if do_plot:
        state.plot()

    return state
 def view_truck_routes():
     now = datetime.datetime.now()
     print("\n\t▪■▪ TRUCK ONE ▪■▪\nClock Time   Miles   Location ID Path")
     truck1 = ds.truck_routes(
         Truck(1, now.replace(hour=8, minute=0, second=0)), first_bundle)
     print("\n\t▪■▪ TRUCK TWO ▪■▪\nClock Time   Miles   Location ID Path")
     truck2 = ds.truck_routes(
         Truck(2, now.replace(hour=9, minute=5, second=0)), second_bundle)
     print("\n\t▪■▪ TRUCK THREE ▪■▪\nClock Time   Miles   Location ID Path")
     truck3 = ds.truck_routes(
         Truck(3, now.replace(hour=10, minute=0, second=0)), third_bundle)
     print("\n🚚 ID     MILEAGE\n\t1\t\t",
           truck1,
           "\n\t2\t\t",
           truck2,
           "\n\t3\t\t",
           truck3,
           "\n           ",
           truck1 + truck2 + truck3,
           end=" TOTAL\n\n")
Example #16
0
 def test_is_empty(self):
     truck = Truck([5, 7, 0, 3], [3, 2, 4, 1])
     expected = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
     self.assertEqual(truck.is_empty(), False)
     for expect in expected:
         truck.pop_product()
         is_empty = truck.is_empty()
         self.assertEqual(is_empty, expect)
Example #17
0
    def start_delivery(self):
        self.arrange_trucks()
        # Call a function to optimized each truck
        for truck in self._trucksList:
            optimized_truck = Truck()
            optimized_truck.add_start_time(truck.truck_start_time())
            optimized_truck.add_time_to_delivery_map(truck.truck_start_time())
            ready_truck = self.optimize_delivery(HUB, truck, optimized_truck)
            self._optimizedTruckList.append(ready_truck)
            self._optimizedTruckDict[truck.truck()] = ready_truck

        # call function to put times for each package delivered
        for truck in self._optimizedTruckList:
            self.set_delivery_time(truck)
Example #18
0
    def _prepare_truck_lists(solution, problem_instance, truck_num_var, dock_num_var, priority_var, num_prod_var):
        truck_dock_association = solution[0:problem_instance[truck_num_var]]

        truck_dock_association = [[index, int(x * problem_instance[dock_num_var])] for index, x in
                                  enumerate(truck_dock_association)]
        priorities = solution[problem_instance[truck_num_var]:]
        trucks_list = []
        trucks_for_inbound_docks = []
        for dock_id in range(0, problem_instance[dock_num_var]):
            trucks_for_inbound_docks.append([])
            trucks_list.append([])
            for association in truck_dock_association:
                if association[1] == dock_id:
                    trucks_for_inbound_docks[dock_id].append([association[0], priorities[association[0]]])
            trucks_for_inbound_docks[dock_id].sort(key=lambda x: x[1])
            for truck in trucks_for_inbound_docks[dock_id]:
                trucks_list[dock_id].append(
                    Truck(problem_instance[num_prod_var][truck[0]], problem_instance[priority_var][truck[0]]))

        return trucks_list
def import_solution(problem, filename):
    with open(path + filename + ".txt") as f:
        customers = import_customers(problem + ".txt", False)
        Distances.calculate_matrix(customers)
        lines = f.readlines()

        ids = []
        for line in lines[5:]:
            ids.append(line.split()[3:])

    routes = []
    for line in ids:
        route = []
        for cust_number in line:
            route.append((customers[int(cust_number) - 1]))
        routes.append(route)

    trucks = []
    for i in range(len(routes)):
        trucks.append(Truck(i, 0, 0, len(routes), Path(routes[i])))

    return State(trucks)
Example #20
0
    def __init__(self,
                 package_controller: PackageController,
                 location_controller: LocationController,
                 city_map: Graph,
                 num_of_trucks: int = 3,
                 number_of_drivers: int = 2) -> None:
        super().__init__()
        self.hub_location = location_controller.locations[0]
        self.city_map = city_map
        self.total_distance = 0

        now = datetime.now()

        self.startOfDay = datetime(now.year, now.month, now.day, 8)
        self.endOfDay = datetime(now.year, now.month, now.day, 17)

        self.current_time = self.startOfDay

        self.package_controller = package_controller

        self.num_of_trucks = num_of_trucks
        self.num_of_drivers = number_of_drivers

        self.trucks: List[Truck] = []
        drivers = self.num_of_drivers
        for index in range(num_of_trucks):
            has_driver = False
            #used positional agruments for better readability on the truck id argument
            if drivers > 0:
                has_driver = True
                drivers -= 1
            truck = Truck(id=index + 1,
                          hub=self.hub_location,
                          has_driver=has_driver,
                          city_map=self.city_map)
            self.trucks.append(truck)
    def __init__(self, distances, locations, packages):
        self.packages = packages
        self.locations = locations

        # Set the hub location from the locations table
        hub = locations["4001 South 700 East"]

        # Make the three trucks
        self.t1 = Truck(1, distances, hub)
        self.t2 = Truck(2, distances, hub)
        self.t3 = Truck(3, distances, hub)

        # Special package rules - sorted by hand based on time or on restrictions
        # about what needs to be delivered together
        for_t1 = [13, 14, 15, 16, 19, 20, 30, 31, 34, 37, 29]
        for_t2 = [1, 3, 6, 18, 25, 28, 32, 36, 38]
        for_t3 = [9]

        # Load the reserved packages into their respective trucks
        load_truck_from_list(self.t1, for_t1, self.packages)
        load_truck_from_list(self.t2, for_t2, self.packages)
        load_truck_from_list(self.t3, for_t3, self.packages)
Example #22
0
 def create() -> Truck:
     return Truck("Howo")
Example #23
0
               "4 : Get status of all packages" - Get and displays status of all packages after delivery route completion
               "5 : End delivery route"
        Helper functions from the Helper class provide the logic for each menu_selection
        Truck loads (lists) manually created to efficiently load truck while taking into account special instructions
        All truck loads are stored in a 2D list for each retrieval within start_delivery_route()
        Helper.clock datetime initialized to beginning of day 08:00:00
        Delivery of all packages orchestrated - Truck.start_delivery_route()
    """
    menu_selection = Helper.display_menu(route_started)

    # delivery route starts if user selects 1 and the route has not started yet
    if menu_selection == "1" and not route_started:
        route_started = True
        print("\n[Delivery Route Started]")

        truck1 = Truck(1, "Driver 1")
        truck2 = Truck(2, "Driver 2")

        # Assign packages to truck for each visit to hub
        truck1_first_load = [4, 13, 14, 15, 16, 17, 19, 20, 21, 34, 39, 40]
        truck2_first_load = [
            1, 2, 3, 5, 7, 8, 18, 22, 27, 29, 30, 33, 35, 36, 37, 38
        ]
        truck1_second_load = [6, 10, 11, 12, 25, 26, 28, 31, 32]
        truck2_second_load = [9, 23, 24]

        # Consolidate lists
        loading_sequence = [[truck1_first_load, truck1_second_load],
                            [truck2_first_load, truck2_second_load]]

        # Number of loading seqs for truck 1
Example #24
0
    def get_children(self,
                     big=True,
                     medium=True,
                     small=True,
                     extra_big_move_children=False,
                     near_valid=False):
        children = []  # list of states
        children_paths = []
        paths = self.paths
        n_customers = len(Distances.matrix[0]) - 1
        trucks = self.trucks

        if big:
            #good
            #children_paths += State.shuffle( paths, 5 )
            #might be good or not, we've never used it
            #children_paths += State.alternating_shuffle_within_path( paths )
            children_paths += State.large_reconstruction(
                paths, 100 if extra_big_move_children else 50)
        if medium:
            if random.random() > 0.8:
                children_paths += State.random_nearest_neighbors(
                    paths, 5, 10
                )  #don't make n_touched bigger than 20 or else it won't work
                children_paths += State.use_clusters(paths, 10)
                children_paths += State.move_central_customers_to_path_starts_and_ends(
                    paths, n_customers // 5)
        if small:
            # good
            # @TODO -- check that they are right
            # children_paths += State.wait_time_swap(paths)
            # children_paths += State.cargo_swap(paths, self.trucks[0].cargo)
            children_paths += State.time_swap(paths)

            children_paths += State.reverse(paths)

            children_paths += State.line_segment_insertion(
                paths, int(n_customers / 5), 15.0)

            children_paths += State.fix_single_unreasonable(paths)

            children_paths += State.fix_group_unreasonable(paths)

            children_paths += State.switch_between_paths(paths, 20)

            children_paths += State.missed_customer_time_swap(paths, 20)

            if near_valid or random.random() > 0.9:
                children_paths += State.swap_all_neighbor_pairs_on_some_path(
                    paths)

            if random.random() > 0.8:
                children_paths += State.path_swap(paths, 20)
                children_paths += State.random_insert(paths, 20)
        # child_paths should be a list containing three paths per entry (as a list)
        for child_paths in children_paths:
            if child_paths:
                trucks = []

                i = 1
                for child in child_paths:
                    trucks.append(Truck(i, 0, 0, self.trucks[0].cargo, child))
                    i += 1

                if sum([len(child) for child in child_paths]) == n_customers:
                    children.append(State(trucks, self))

        return children
Example #25
0
# Josh Gaweda Student ID #: 001150997

from datetime import datetime, timedelta
from HashTable import HashTable
from Package import Package
from Truck import Truck
import re
import os
clear = lambda: os.system('clear') & os.system('cls')

# Creates the global variables for this project (Hash Table, Time, Trucks)
receiveing = HashTable()
global_time = datetime(2021, 1, 10, 8, 00)
truck1 = Truck(receiveing.init1(), datetime(2021, 1, 10, 9, 5), 1, receiveing)
truck2 = Truck(receiveing.init2(), datetime(2021, 1, 10, 8, 00), 2, receiveing)
truck3 = Truck(receiveing.init3(), datetime(2021, 1, 10, 23, 59), 3,
               receiveing)


def start_deliveries(delivery_time=datetime(2021, 1, 10, 23, 59)):
    # Space-time complexity = O(N)
    # Runs all deliveries until global time matches the delivery time.
    # This function will start each truck at the appropriate time, including truck 3 which will leave when another comes back.
    # Stops running deliveries once every package is delivered and all trucks returned to hub.

    global global_time
    while global_time < delivery_time:

        # Starts truck 3
        if truck3.status == 'AT HUB, START OF DAY' and truck2.status == 'Deliveries complete' or truck1.status == 'Deliveries complete':
            truck3.time = global_time
Example #26
0
    def run(self):
        self.trucks.append(Truck(self.capacity))

        final_cost = 0
        visited_cost = 0
        current_truck = 0
        n_nodes = self.dimension - 1

        while n_nodes > 0:
            chosen_index = 0
            chosen_node = None
            min_cost = inf

            # check if truck path is empty
            if len(self.trucks[current_truck].path) == 0:
                self.trucks[current_truck].add_to_path(self.nodes[0])
                self.nodes[0].visited = True
                if current_truck == 0:
                    random_node = None
                    while True:
                        random_node = choice(self.nodes)
                        if self.trucks[current_truck].available_load(
                        ) >= random_node.demand:
                            break

                    random_node = choice(self.nodes)
                    truck = self.trucks[current_truck]
                    prev_location = truck.path[0]
                    truck.add_to_path(random_node)
                    truck.add_load(random_node.demand)
                    truck.current_location = int(random_node.id)
                    self.nodes[random_node.id].visited = True
                    final_cost += self.cost_matrix[prev_location.id][
                        self.trucks[current_truck].current_location]
                    n_nodes -= 1

            # run the greedy algorithm
            for i in range(self.dimension):
                if not self.nodes[i].visited:
                    if self.trucks[current_truck].available_load(
                    ) >= self.nodes[i].demand:
                        visited_cost = self.cost_matrix[
                            self.trucks[current_truck].current_location][i]
                        if visited_cost < min_cost:
                            min_cost = visited_cost
                            chosen_index = i
                            chosen_node = self.nodes[i]

            # if we can choose a node
            if chosen_node != None:
                truck = self.trucks[current_truck]
                truck.add_to_path(chosen_node)
                truck.add_load(chosen_node.demand)
                truck.current_location = int(chosen_node.id)
                self.nodes[chosen_index].visited = True
                final_cost += min_cost
                n_nodes -= 1
            else:
                # Changing truck

                if int(self.trucks[current_truck].current_location) != 0:
                    final_cost += self.cost_matrix[
                        self.trucks[current_truck].current_location][0]
                    self.trucks[current_truck].add_to_path(self.nodes[0])

                self.trucks.append(Truck(self.capacity))
                current_truck += 1

        # taker last truck to the depot
        final_cost += self.cost_matrix[
            self.trucks[current_truck].current_location][0]
        self.trucks[current_truck].add_to_path(self.nodes[0])

        routes = []

        i = 0
        for truck in self.trucks:
            # print("Truck:", i)
            # print(truck.get_path_ids())
            routes.append(truck.get_path_ids())
            i += 1

        return final_cost, routes
Example #27
0
class TruckManager:
    truck_1 = Truck(truck_id='truck_1')
    truck_2 = Truck(truck_id='truck_2')
    truck_3 = Truck(truck_id='truck_3')

    #######
    # O(1) - constant
    # creates new truck objects (used for completing deliveries multiple times over)
    @classmethod
    def reset_trucks(cls):
        cls.truck_1 = Truck(truck_id='truck_1')
        cls.truck_2 = Truck(truck_id='truck_2')
        cls.truck_3 = Truck(truck_id='truck_3')

    #######
    # O(1) - constant
    # to_string formatter for the TruckManager object
    @classmethod
    def __str__(cls):
        return '''TruckManager: ( 
                    truck_1: {},
                    truck_2: {},
                    truck_3: {}
              ) 
        '''.format(cls.truck_1.packages, cls.truck_2.packages, cls.truck_3.packages)

    #######
    # O(N^2) - quadratic (calls 'send_out_truck' which is a quadratic function)
    # sends out trucks based on driver availability
    @classmethod
    def run_fleet(cls, distance_table):
        cls.send_out_truck(cls.truck_1, distance_table, Clock('8:00', 'AM'))
        cls.send_out_truck(cls.truck_2, distance_table, Clock('11:30', 'AM'))
        cls.send_out_truck(cls.truck_3, distance_table, Clock('9:10', 'AM'), ignore_deadline=True)

    #######
    # O(N^2) - quadratic time.
    # Delivers all packages that were loaded onto a specific truck
    @classmethod
    def send_out_truck(cls, truck, distance_table, start_clock, ignore_deadline=False):
        truck.start_clock(start_clock)

        # Loops until all packages in truck are delivered
        # 1. First checks if more than one package go to the same address
        # 2. Second checks if any deadlines are approaching that need to be prioritized
        # 3. Lastly, uses a greedy algorithm to find nearest location to deliver next package
        while not truck.is_route_finished() and not truck.clock_stopped():
            package_with_deadline = truck.approaching_deadline() if not ignore_deadline else None
            package_for_same_address = truck.package_for_current_address()
            if package_for_same_address is not None:
                next_delivery = package_for_same_address
            elif package_with_deadline is not None:
                next_delivery = package_with_deadline
            else:
                next_delivery = cls.get_closest_package(truck, distance_table)
            truck.deliver_package(next_delivery, distance_table)
        # After all packages are delivered drive back to HUB
        truck.drive_back_to_hub(distance_table)

    #######
    # O(N) - linear
    # greedy algorithm (find closest destination from current location)
    @classmethod
    def get_closest_package(cls, truck, distance_table):
        closest_package = truck.get_first_undelivered_package()
        closest_distance = distance_table.get_distance(truck.location, closest_package.address)

        for package in truck.packages:
            if package.status == PackageStatuses.DELIVERED:
                continue

            other_distance = distance_table.get_distance(truck.location, package.address)
            if other_distance < closest_distance:
                closest_package = package
                closest_distance = other_distance

        return closest_package

    #######
    # O(N) - linear
    # loads each package onto a given truck
    @classmethod
    def load_truck(cls, truck, package_list, package_table):
        for package_id in package_list:
            package = package_table.get(str(package_id))
            truck.load_package(package)

    #######
    # O(1) - constant
    # sets stop time on trucks. used for reporting status at a specific time of the day
    @classmethod
    def set_stop_time(cls, stop_time):
        time = stop_time[0: stop_time.index(' ')]
        period = stop_time[stop_time.index(' ') + 1:]

        cls.truck_1.stop_clock = Clock(time, period)
        cls.truck_2.stop_clock = Clock(time, period)
        cls.truck_3.stop_clock = Clock(time, period)

    #######
    # O(1) - constant
    # simply adds all miles traveled by all trucks
    @classmethod
    def get_miles_traveled_by_all_trucks(cls):
        return cls.truck_1.miles_traveled \
               + cls.truck_2.miles_traveled \
               + cls.truck_3.miles_traveled

    #######
    # O(N) - linear
    # report for the package information by delivery truck
    @classmethod
    def print_report(cls):
        PACKAGE_TABLE_HEADER = '|\tID\t|\tDELIVERY ADDRESS\t\t|\tCITY\t\t\t|\tSTATE\t|\tZIP\t\t|\tDEADLINE\t|\tWEIGHT\t' \
                               '|\tSTATUS\t\t|\tDELIVERY TIME\t|\tINSTRUCTIONS'
        hr = '--------------------------------------------------------------------------------------------------------' \
             '--------------------------------------------------------'
        print('////////////////////////////////////////////////////////')
        print('PACKAGE REPORT (BY TRUCK)\n')
        print('Truck 1: location {}, time arrived: {}, miles traveled {}'
              .format(cls.truck_1.location, cls.truck_1.clock.time_string(), cls.truck_1.miles_traveled))

        print(hr + '\n' + PACKAGE_TABLE_HEADER + '\n' + hr)
        for package in cls.truck_1.packages:
            print(cell_row_of(package))

        print('\n\nTruck 2: location {}, time arrived: {}, miles traveled {}'
              .format(cls.truck_2.location, cls.truck_2.clock.time_string(), cls.truck_2.miles_traveled))
        print(hr + '\n' + PACKAGE_TABLE_HEADER + '\n' + hr)
        for package in cls.truck_2.packages:
            print(cell_row_of(package))

        print('\n\nTruck 3: location {}, time arrived: {}, miles traveled {}'
              .format(cls.truck_3.location, cls.truck_3.clock.time_string(), cls.truck_3.miles_traveled))
        print(hr + '\n' + PACKAGE_TABLE_HEADER + '\n' + hr)
        for package in cls.truck_3.packages:
            print(cell_row_of(package))

        print('\n\nTotal miles traveled: {}'.format(cls.get_miles_traveled_by_all_trucks()))
        print('////////////////////////////////////////////////////////')
Example #28
0
 def reset_trucks(cls):
     cls.truck_1 = Truck(truck_id='truck_1')
     cls.truck_2 = Truck(truck_id='truck_2')
     cls.truck_3 = Truck(truck_id='truck_3')
Example #29
0
#Jeffery Burroughs
#876696

from Graph import Graph
from Graph import Vertex
from Pack import Package
from Hash import pkg_hash
import datetime
from Truck import Truck
import operator

location_list = []
the_graph = Graph()
time = [8,0]
total_mileage = 0
trucks = [Truck(1), Truck(2)]
HUB = 0

def sort_packages(the_truck: Truck):  

    #Sort function begins by sorting all packages with early delivery
    #to the front of the package_list using a bubble sort. The next step
    #is to group any packages with the same destination. The final step is
    #to bubble sort all packages, starting with the first EOD delivery, based
    #on nearest neighbor.
   

    def sort_for_early_delivery(package_list):

    #Bubblesort the package_list to sort by deadline. If iterate through list and compare
    #based on deadline. If deadline is less move towards the front of the list.
Example #30
0
# ---------Values that make the most difference in this program------------
# Max values to lookahead (computational complexity is very sensitive to increases - max recommended is 9, which takes
# about 150 seconds to run on my machine.
MAX_LOOKAHEAD = 9
# --------------------Don't change these values-------------------
# Absolute package limit for each truck
ABSOLUTE_PACKAGE_LIMIT = 16
# If less than 16, designates truck #2 as a shorter loop truck so it returns to the hub more often to get priority
# packages
SHORTER_PACKAGE_LIMIT = 16
# ------------------------------------------------------------------

# -------Initializations-------
# trucks
Truck(1)
Truck(2)
all_trucks = Truck.get_all_trucks()

# -------Imports-------

# ---Locations---
graph_input = pd.read_excel("WGUPS Distance Table.xlsx", header=0, index_col=0, engine="openpyxl")
locations = graph_input.columns.tolist()
# This is needed for iterating through the new locations later
try:
    start_location_num = Location.max_location_number()
except ValueError:
    start_location_num = 0
# Get the graph and distances between points
# Unfortunately I wrote the PathGraph and Dijkstra's with lists before I decided to do input via pandas