Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug fixing and modifying genetic algorithm #48

Merged
merged 23 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion experiments/algorithms_2_multi_agency.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def log(message: str, logfile: IO):
schedulers = [HEFTScheduler(),
HEFTBetweenScheduler(),
TopologicalScheduler()]
# GeneticScheduler(50, 50, 0.5, 0.5, 20)]
# GeneticScheduler(50, 0.5, 0.5, 20)]

contractors = [p_rand.contractor(10) for _ in range(len(schedulers))]

Expand Down
10 changes: 5 additions & 5 deletions experiments/genetic_2_multi_agency.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ def obstruction_getter(i: int):


if __name__ == '__main__':
schedulers = [GeneticScheduler(50, 50, 0.5, 0.5, 100),]
# GeneticScheduler(50, 50, 0.5, 0.5, 100),
# GeneticScheduler(50, 50, 0.5, 0.5, 100),
# GeneticScheduler(50, 50, 0.5, 0.5, 100),
# GeneticScheduler(50, 50, 0.5, 0.5, 100)]
schedulers = [GeneticScheduler(50, 0.5, 0.5, 100),]
# GeneticScheduler(50, 0.5, 0.5, 100),
# GeneticScheduler(50, 0.5, 0.5, 100),
# GeneticScheduler(50, 0.5, 0.5, 100),
# GeneticScheduler(50, 0.5, 0.5, 100)]

contractors = [p_rand.contractor(10) for _ in range(len(schedulers))]

Expand Down
20 changes: 10 additions & 10 deletions experiments/modular_examples/multi_agency_comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,16 @@ def run_iteration(args):
if mode == 0:
schedulers = [HEFTScheduler(), HEFTBetweenScheduler(), TopologicalScheduler()]
else:
schedulers = [GeneticScheduler(50, 50, 0.5, 0.5, 100),
GeneticScheduler(50, 100, 0.25, 0.5, 100),
GeneticScheduler(50, 100, 0.5, 0.75, 100),
GeneticScheduler(50, 100, 0.75, 0.75, 100),
GeneticScheduler(50, 50, 0.9, 0.9, 100),
GeneticScheduler(50, 100, 0.5, 0.5, 500),
GeneticScheduler(50, 200, 0.25, 0.5, 500),
GeneticScheduler(50, 50, 0.5, 0.75, 500),
GeneticScheduler(50, 100, 0.75, 0.75, 500),
GeneticScheduler(50, 50, 0.5, 0.9, 500)]
schedulers = [GeneticScheduler(50, 0.5, 0.5, 100),
GeneticScheduler(50, 0.25, 0.5, 100),
GeneticScheduler(50, 0.5, 0.75, 100),
GeneticScheduler(50, 0.75, 0.75, 100),
GeneticScheduler(50, 0.9, 0.9, 100),
GeneticScheduler(50, 0.5, 0.5, 500),
GeneticScheduler(50, 0.25, 0.5, 500),
GeneticScheduler(50, 0.5, 0.75, 500),
GeneticScheduler(50, 0.75, 0.75, 500),
GeneticScheduler(50, 0.5, 0.9, 500)]
variate_block_size(logfile, schedulers)


Expand Down
41 changes: 12 additions & 29 deletions sampo/scheduler/genetic/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import math
import random
from typing import Optional, Callable

Expand Down Expand Up @@ -33,7 +32,6 @@ class GeneticScheduler(Scheduler):

def __init__(self,
number_of_generation: Optional[int] = 50,
size_selection: Optional[int or None] = None,
mutate_order: Optional[float or None] = None,
mutate_resources: Optional[float or None] = None,
size_of_population: Optional[float or None] = None,
Expand All @@ -49,64 +47,50 @@ def __init__(self,
resource_optimizer=resource_optimizer,
work_estimator=work_estimator)
self.number_of_generation = number_of_generation
self.size_selection = size_selection
self.mutate_order = mutate_order
self.mutate_resources = mutate_resources
self.size_of_population = size_of_population
self.rand = rand or random.Random(seed)
self.fitness_constructor = fitness_constructor
self.work_estimator = work_estimator
self._n_cpu = n_cpu
self._weights = None
self._weights = weights

self._time_border = None
self._deadline = None

def __str__(self) -> str:
return f'GeneticScheduler[' \
f'generations={self.number_of_generation},' \
f'size_selection={self.size_selection},' \
f'population_size={self.size_of_population},' \
f'mutate_order={self.mutate_order},' \
f'mutate_resources={self.mutate_resources}' \
f']'

def get_params(self, works_count: int) -> tuple[int, float, float, int]:
def get_params(self, works_count: int) -> tuple[float, float, int]:
"""
Return base parameters for model to make new population

:param works_count:
:return:
"""
size_selection = self.size_selection
if size_selection is None:
if works_count < 300:
size_selection = 20
else:
size_selection = works_count // 15

mutate_order = self.mutate_order
if mutate_order is None:
if works_count < 300:
mutate_order = 0.05
else:
mutate_order = 2 / math.sqrt(works_count)
mutate_order = 0.05

mutate_resources = self.mutate_resources
if mutate_resources is None:
if works_count < 300:
mutate_resources = 0.1
else:
mutate_resources = 6 / math.sqrt(works_count)
mutate_resources = 0.005

size_of_population = self.size_of_population
if size_of_population is None:
if works_count < 300:
size_of_population = 20
elif 1500 > works_count >= 300:
size_of_population = 50
elif 1500 > works_count >= 300:
size_of_population = 100
else:
size_of_population = works_count // 50
return size_selection, mutate_order, mutate_resources, size_of_population
size_of_population = works_count // 25
return mutate_order, mutate_resources, size_of_population

def set_use_multiprocessing(self, n_cpu: int):
"""
Expand All @@ -130,8 +114,8 @@ def set_deadline(self, deadline: Time):
def set_weights(self, weights: list[int]):
self._weights = weights

@classmethod
def generate_first_population(self, wg: WorkGraph, contractors: list[Contractor],
@staticmethod
def generate_first_population(wg: WorkGraph, contractors: list[Contractor],
landscape: LandscapeConfiguration = LandscapeConfiguration(),
spec: ScheduleSpec = ScheduleSpec(),
work_estimator: WorkTimeEstimator = None,
Expand Down Expand Up @@ -213,15 +197,14 @@ def schedule_with_cache(self,
init_schedules = GeneticScheduler.generate_first_population(wg, contractors, landscape, spec,
self.work_estimator, self._deadline, self._weights)

size_selection, mutate_order, mutate_resources, size_of_population = self.get_params(wg.vertex_count)
mutate_order, mutate_resources, size_of_population = self.get_params(wg.vertex_count)
worker_pool = get_worker_contractor_pool(contractors)

scheduled_works, schedule_start_time, timeline, order_nodes = build_schedule(wg,
contractors,
worker_pool,
size_of_population,
self.number_of_generation,
size_selection,
mutate_order,
mutate_resources,
init_schedules,
Expand Down
Loading