Example #1
0
 def _create_crossover(self, next_population_parents):
     crossovers = []
     s_print("Adding crossovers --- STARTED")
     while len(crossovers) < self.population_limit * cross_over_ratio:
         crossovers.extend(crossover(next_population_parents))
     s_print("Adding crossovers --- FINISHED")
     return crossovers
Example #2
0
def create_mutation_thread(process_name, mutations, next_generation_parents):
    while True:
        mutation = mutate(next_generation_parents)
        if not (mutations.append(mutation)):
            break
        s_print("{} mutated with energy cost ${}".format(
            process_name, mutation.total_energy_cost()))
Example #3
0
 def _create_mutation(self, next_population_parents):
     mutations = []
     s_print("Adding mutations --- STARTED")
     while len(mutations) < self.population_limit * mutation_ratio:
         mutations.append(mutate(next_population_parents))
     s_print("Adding mutations --- FINISHED")
     return mutations
Example #4
0
def mutate(next_population_parents):
    """
    Args:
        next_population_parents: next generation parents
    Returns:
        mutated child assignment
    """
    parent = random.choice(next_population_parents.copy())
    mutation_count = max(min_mutation,
                         int(mutation_prob * len(parent.get_trips())))
    at_least_one_mutated = False
    start_time = datetime.now()
    parent_cpy = parent.copy()
    child = None
    while mutation_count > 0:
        if (datetime.now() -
                start_time).total_seconds() > mutation_break_time_limit:
            if not at_least_one_mutated:
                s_print("Nothing mutated breaking due to time limitation")
            break
        child, mutated = parent_cpy.mutate()
        if mutated:
            at_least_one_mutated = True
            mutation_count -= 1
            parent_cpy = child.copy()
        else:
            parent_cpy = parent.copy()

    if child is None:
        child = parent.copy()
    return child.copy()
Example #5
0
 def assign(self, selected_trip, selected_bus):
     status = False
     if selected_trip not in self._trip_alloc:
         _info = self.add(selected_trip, selected_bus)
         if _info.feasible():
             self._trip_alloc.append(selected_trip)
             self._update_stats(selected_bus)
             status = True
         else:
             if is_electric(selected_bus):
                 if _info.time_feasible() and not _info.energy_feasible():
                     _res_info = self.assign_charge(_info, selected_bus,
                                                    selected_trip)
                     if _res_info.feasible():
                         _res_info_add = self.add(selected_trip,
                                                  selected_bus)
                         if _res_info_add.feasible():
                             self._trip_alloc.append(selected_trip)
                             status = True
                 else:
                     if isinstance(selected_trip, OperatingTrip):
                         if electric_bus_type.capacity < selected_trip.get_energy_consumed(
                                 electric_bus_type):
                             s_print(_info.energy())
                             raise NotEnoughEVEnergyException(
                                 "EVBusEnergy is not enough for a single trip !!!"
                             )
                     else:
                         s_print(_info.energy())
                         raise NotEnoughEVEnergyException(
                             "EVBusEnergy is not enough for a single trip !!!"
                         )
         return status
 def print(self, info=""):
     print_hf(stat_header_length, info=info)
     super(BusStat, self).print()
     print_hf(movements_header_length, info="BUS MOVEMENTS")
     for time_in_seconds in sorted(self.movements.keys()):
         s_movement = self.movements[time_in_seconds]
         for movement in s_movement:
             s_print(movement.__str__())
Example #7
0
def create_population_thread(process_name, populations, dump_structure,
                             assign_util_config, arg):
    while True:
        assignment = assign(dump_structure, assign_util_config, arg)
        assign_type = assignment.get_type()
        if assignment is not None:
            if not (populations.append(assignment)):
                break
            s_print(
                "{} assigned with energy cost ${} using Algorithm {}".format(
                    process_name, assignment.total_energy_cost(),
                    str(assign_type)))
Example #8
0
def create_crossover_thread(process_name, cross_overs,
                            next_generation_parents):
    while True:
        cross_over_set = crossover(next_generation_parents)
        if not (cross_overs.append(cross_over_set[0])):
            break
        s_print("{} crossover with energy cost ${}".format(
            process_name, cross_over_set[0].total_energy_cost()))
        if not (cross_overs.append(cross_over_set[1])):
            break
        s_print("{} crossover with energy cost ${}".format(
            process_name, cross_over_set[1].total_energy_cost()))
Example #9
0
 def __do_dummy_assign(self):
     operating_trips = self.dump_structure.filtered_trips.copy()
     if self.assign_util_config.dummy_assign:
         if self.required_assignments > 0:
             for trip in operating_trips:
                 dummy_bus = DummyBus(str(self.required_assignments))
                 success = self.assignment.assign(trip, dummy_bus)
                 if success:
                     self.required_assignments -= 1
                     if self.required_assignments == 0:
                         break
         s_print("Dummy Missing Assignments {}".format(
             str(self.required_assignments)))
Example #10
0
 def finalize(self, skip_dummy=False):
     s_print("Expected Dummy Assignments {}".format(
         str(self.required_assignments)))
     if skip_dummy:
         self.__do_dummy_assign()
     if self.assign_util_config.compute:
         self.assignment.write(self.dump_structure.__key__() + "_" +
                               self.additional_prefix)
         self.assignment.write_bus_stat(self.dump_structure.__key__(),
                                        self.additional_prefix,
                                        self.assign_util_config.do_print)
     if self.required_assignments == 0:
         self.assignment.complete = True
 def get_obj_status(self):
     objective = "NA"
     gap = "NA"
     s_print("Solution status = " + str(self.solution.get_status()) + ":",
             end=False)
     status = self.solution.status[self.solution.get_status()]
     try:
         objective = round(self.solution.get_objective_value(), 5)
         gap = round(self.solution.MIP.get_mip_relative_gap() * 100, 2)
         s_print("Solution value  = " + str(objective))
     except cplex.exceptions.errors.CplexSolverError:
         s_print_err("Solution not exists exiting the program")
         exit(-1)
     return objective, status, gap
 def print(self):
     s_print("No of Routes : {}".format(str(self._dump_config.route_limit)))
     s_print("No of Trips per route : {}".format(
         str(self._dump_config.trip_limit)))
     s_print("No of Electric Vehicles : {}".format(
         str(self._dump_config.ev_count)))
     s_print("No of Gas Vehicles : {}".format(
         str(self._dump_config.gv_count)))
def print_hf(half_count, char=stat_decorator_char, info=""):
    for i in range(half_count):
        s_print(char, end=False)
    if info != "":
        s_print(" " + info + " ", end=False)
    for i in range(half_count):
        s_print(char, end=False)
    s_print("")
def create_assignment(assign_type=None, dump_structure=None, args=None):
    if args is None:
        interface = ""
    else:
        interface = args.interface
    if issubclass(assignment_class, AssignmentWTC):
        if dump_structure is not None:
            if interface == "":
                assignment = AssignmentWTC(assign_type,
                                           dump_structure.charging)
            elif interface == "GAAction":
                assignment = AssignmentWTCGA(assign_type,
                                             dump_structure.charging)
            elif interface == "SAAction":
                assignment = AssignmentWTCSA(assign_type,
                                             dump_structure.charging)
            else:
                raise ValueError("Invalid interface: {}".format(interface))
        else:
            raise DumpStructureMissingException("Dump structure is missing")
    elif issubclass(assignment_class, Assignment):
        if interface == "":
            assignment = Assignment(assign_type)
        elif interface == "GAAction":
            assignment = AssignmentGA(assign_type)
        elif interface == "SAAction":
            assignment = AssignmentSA(assign_type)
        else:
            raise ValueError("Invalid interface: {}".format(interface))
    else:
        raise InvalidAssignmentClassException(
            "Invalid Assignment Class {}".format(assignment_class.__name__))
    if assign_type == AssignTypes.GREEDY:
        if args is not None:
            s_print("Greedy configs: \nev weight: {}\ngv weight: {}".format(
                args.weight_ev, args.weight_gv))
            assignment.set_weight(args.weight_ev, args.weight_gv)
        else:
            raise ValueError("Missing arguments")
    return assignment
def nearest_neighbour(assignment, swap_prob):
    """
    Returns:
        nearest neighbor assignment
    """
    swap_count = max(1, int(swap_prob * len(assignment.get_trips())))
    at_least_one_swapped = False
    start_time = datetime.now()
    child = None
    while swap_count > 0:
        if (datetime.now() - start_time).total_seconds() > 4:
            if not at_least_one_swapped:
                s_print("Nothing modified breaking due to time limitation")
            break
        child, swapped = assignment.swap()
        if swapped:
            at_least_one_swapped = True
            swap_count -= 1

    if child is None:
        child = assignment
    return child
Example #16
0
 def run(self, arg):
     start_time = datetime.now()
     self._init_population(arg)
     convergence_limit = 0
     minimum_cost = math.inf
     new_population = self.sys_population
     generation = 0
     self.summary_file_name = summary_directory + "genetic_algorithm.csv"
     create_dir(summary_directory)
     summary_file = FileWriter(self.summary_file_name)
     summary_file.write("iteration,energy_cost")
     while convergence_limit < gen_alg_convergence_limit and generation < self.generation_limit:
         s_print("Current Generation {}".format(str(generation)))
         scores = score_population(new_population)
         best = new_population[scores.index(min(scores))]
         fitness_cost = fitness(best)
         self.best_costs.append(fitness_cost)
         if fitness_cost < minimum_cost:
             convergence_limit = 0
             minimum_cost = fitness_cost
             self.over_all_best = best
         else:
             convergence_limit += 1
         summary_file.write([generation, minimum_cost])
         new_population = select(
             new_population,
             max(int(len(new_population) * selection_ratio), min_pop))
         s_print("Creating next generation ")
         new_population.extend(self._create_crossover(new_population))
         new_population.extend(self._create_mutation(new_population))
         self.population_limit = len(new_population)
         self.generation_count = generation
         generation += 1
     summary_file.close()
     end_time = datetime.now()
     self.time_consumed = (end_time - start_time).total_seconds()
     s_print("Total time taken is " + time(int(self.time_consumed)).time)
     if self.over_all_best is not None:
         if isinstance(self.over_all_best, Assignment):
             self.over_all_best.write(self.dump_structure.__key__())
             self.over_all_best.write_bus_stat(
                 self.dump_structure.__key__(), do_print=True)
    def run(self, dump_structure, args):
        cycle_count = int(args.cycle_count)
        start_prob = float(args.start_prob)
        end_prob = float(args.end_prob)
        swap_prob = float(args.swap_prob)

        swap_condition = 0 < swap_prob < 1
        start_end_condition = 0 < end_prob < start_prob < 1

        s_print("Simulated annealing configs: \ncycle Count: {}\nstart prob: {}\nend prob: {}\nswap prob: {}".
                format(args.cycle_count, args.start_prob, args.end_prob, args.swap_prob))

        if not swap_condition or not start_end_condition:
            raise ValueError("inconsistent parameters")

        assignment = greedy_assign(dump_structure, AssignUtilConfig(do_print=True), args=args)
        energy_cost = assignment.total_energy_cost()
        self.min_assign = assignment
        self.min_cost = energy_cost

        temp_start = -1.0 / math.log(start_prob)
        temp_end = -1.0 / math.log(end_prob)
        rate_of_temp = (temp_end / temp_start) ** (1.0 / (cycle_count - 1.0))

        selected_temp = temp_start
        delta_e_avg = 0.0
        number_of_accepted = 1
        prefix = "{}_{}_{}_".format(args.start_prob, args.end_prob, args.swap_prob)
        prefix = prefix.replace(".", "_")
        self.summary_file_name = summary_directory + prefix + "simulated_annealing.csv"
        create_dir(summary_directory)
        summary_file = FileWriter(self.summary_file_name)
        summary_file.write("iteration,energy_cost")
        summary_file.write([0, energy_cost])
        for i in range(cycle_count):
            s_print('Cycle: {} with Temperature: {}'.format(str(i), str(selected_temp)))
            nn_assignment = nearest_neighbour(assignment, swap_prob)
            nn_energy_cost = nn_assignment.total_energy_cost()
            delta_e = abs(nn_energy_cost - energy_cost)
            if nn_energy_cost > energy_cost:
                if i == 0:
                    delta_e_avg = delta_e
                denominator = (delta_e_avg * selected_temp)
                p = math.exp(-1 * math.inf) if denominator == 0 else math.exp(-delta_e / denominator)
                accept = True if random.random() < p else False
            else:
                accept = True
            # save current minimum to avoid losing details due to crash
            if self.min_cost > nn_energy_cost:
                self.min_assign = nn_assignment.copy()
                self.min_cost = nn_energy_cost
                nn_assignment.write("current_min")
                nn_assignment.write_bus_stat("current_min")

            if accept:
                assignment = nn_assignment
                energy_cost = nn_energy_cost
                summary_file.write([i, energy_cost])
                delta_e_avg = delta_e_avg + (delta_e - delta_e_avg) / number_of_accepted
                number_of_accepted += 1
            selected_temp = rate_of_temp * selected_temp
        summary_file.close()
        improve_perc = round(100.0 * (energy_cost - self.min_cost) / energy_cost, 3)
        s_print("Improvement in energy cost {}%".format(str(improve_perc)))
    def schedule(self):
        assign_buses = self.dump_structure.all_buses().copy()
        operating_trips = self.dump_structure.filtered_trips.copy()
        self.required_assignments = len(operating_trips)
        assign_type = str(self.assignment.get_type())
        s_print("Expected Assignments {}, Algorithm {}".format(
            str(self.required_assignments), assign_type))
        start_time = datetime.now()
        if self.random_order:
            random.shuffle(operating_trips)
        else:
            operating_trips = sorted(operating_trips,
                                     key=lambda trip: trip.start_s())
        cost_matrix = CostMatrix(self.assignment, operating_trips,
                                 assign_buses)
        while self.required_assignments > 0:
            assigned = False
            _bus_i = -1
            _trip_i = -1
            np_cost_matrix = np.array(cost_matrix.matrix)
            min_cost = np.min(np_cost_matrix)
            if min_cost == math.inf:
                s_print("No more feasible solutions")
                s_print("Remaining trips to be assigned {}".format(
                    str(self.required_assignments)))
                break
            feasible_assign_pairs = np.argwhere(np_cost_matrix == min_cost)
            _trip_i, _bus_i = feasible_assign_pairs[0]
            _trip = operating_trips[_trip_i]
            _bus = assign_buses[_bus_i]
            if (_trip, _bus) in cost_matrix.req_charging.keys():
                _charging = cost_matrix.req_charging[_trip, _bus]
                if self.assignment.assign_charge_force(_charging, _bus):
                    if self.assignment.assign(_trip, _bus):
                        assigned = True
            elif self.assignment.assign(_trip, _bus):
                assigned = True

            if assigned:
                self.required_assignments -= 1
                cost_matrix.update(self.assignment, _bus_i, _trip_i)
            else:
                s_print("Not Assigned !!! No more feasible solutions")
                s_print("Remaining trips to be assigned {}".format(
                    str(self.required_assignments)))
                break
        s_print("{} seconds taken for the computation".format(
            str((datetime.now() - start_time).total_seconds())))
 def print(self):
     RunAssist.print(self)
     s_print("Slot duration : {}".format(self._dump_config.slot_duration))
 def print(self, prefix=""):
     # print only when there is an assignment
     if self.duration.time_in_seconds != 0:
         s_print(prefix + " Duration: " + self.duration.time_h)
         s_print(prefix + " Assignments: " + str(self.count))
         if self.kwh_energy_consumed > 0:
             s_print(prefix + " EV Assignments: " +
                     str(self.electric_count))
             s_print(prefix + " Energy Consumed: " +
                     str(round(self.kwh_energy_consumed, 4)) + " kWh")
         if self.gallon_energy_consumed > 0:
             s_print(prefix + " GV Assignments: " +
                     str(self.gasoline_count))
             s_print(prefix + " Energy Consumed: " +
                     str(round(self.gallon_energy_consumed, 4)) +
                     " gallon(s)")
         energy_cost, emission = self.get_cost_and_emission()
         if energy_cost > 0:
             s_print(prefix + " Energy Cost: $" +
                     str(round(energy_cost, 4)))
         if energy_cost > 0:
             s_print(prefix + " CO2 Emission: " + str(round(emission, 4)) +
                     " kg")