Skip to content

Commit 2c4b4bf

Browse files
committed
v0.1.3 Wrapped a part of score calculation; Comparing with global refactor
1 parent 8cf4354 commit 2c4b4bf

File tree

20 files changed

+140
-98
lines changed

20 files changed

+140
-98
lines changed

examples/object_oriented/nqueens/scripts/solve_nqueens.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,25 @@
2020
if __name__ == "__main__":
2121

2222
# build domain model
23-
domain_builder = DomainBuilderNQueens(10000, random_seed=45)
23+
domain_builder = DomainBuilderNQueens(1024, random_seed=45)
2424
cotwin_builder = CotwinBuilderNQueens(use_incremental_score_calculator=True)
2525

2626
#termination_strategy = StepsLimit(step_count_limit=1000)
27-
termination_strategy = TimeSpentLimit(time_seconds_limit=60)
27+
#termination_strategy = TimeSpentLimit(time_seconds_limit=60)
2828
#termination_strategy = ScoreNoImprovement(time_seconds_limit=15)
29-
#termination_strategy = ScoreLimit(score_to_compare=[0])
29+
termination_strategy = ScoreLimit(score_to_compare=[0])
3030
agent = TabuSearch(neighbours_count=20, tabu_entity_rate=0.0,
3131
mutation_rate_multiplier=None, move_probas=[0, 1, 0, 0, 0, 0],
32-
compare_to_global=True, migration_frequency=10, termination_strategy=termination_strategy)
32+
migration_frequency=10, termination_strategy=termination_strategy)
3333
"""agent = GeneticAlgorithm(population_size=128, crossover_probability=0.5, p_best_rate=0.05,
3434
tabu_entity_rate=0.0, mutation_rate_multiplier=1.0, move_probas=[0, 1, 0, 0, 0, 0],
3535
migration_rate=0.00001, migration_frequency=1, termination_strategy=termination_strategy)"""
3636
"""agent = LateAcceptance(late_acceptance_size=10, tabu_entity_rate=0.0,
3737
mutation_rate_multiplier=None, move_probas=[0, 1, 0, 0, 0, 0],
38-
termination_strategy=termination_strategy)"""
38+
compare_to_global_frequency=1, termination_strategy=termination_strategy)"""
3939
"""agent = SimulatedAnnealing(initial_temperature=[1.0], cooling_rate=0.9999, tabu_entity_rate=0.0,
4040
mutation_rate_multiplier=None, move_probas=[0, 1, 0, 0, 0, 0],
41-
compare_to_global=True, migration_frequency=10, termination_strategy=termination_strategy)"""
41+
migration_frequency=10, compare_to_global_frequency=10, termination_strategy=termination_strategy)"""
4242

4343
solver = Solver(domain_builder, cotwin_builder, agent,
4444
ParallelizationBackend.Multiprocessing, LoggingLevel.FreshOnly,

examples/object_oriented/tsp/scripts/solve_tsp.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
#termination_strategy = ScoreLimit(score_to_compare=[0])
4343
agent = TabuSearch(neighbours_count=128, tabu_entity_rate=0.5,
4444
mutation_rate_multiplier=None, move_probas=[0.0, 0.2, 0.2, 0.2, 0.2, 0.2],
45-
compare_to_global=False, migration_frequency=10, termination_strategy=termination_strategy)
45+
migration_frequency=10, termination_strategy=termination_strategy)
4646
"""agent = GeneticAlgorithm(population_size=128, crossover_probability=0.5, p_best_rate=0.05,
4747
tabu_entity_rate=0.2, mutation_rate_multiplier=1.0, move_probas=[0.0, 0.2, 0.2, 0.2, 0.2, 0.2],
4848
migration_rate=0.00001, migration_frequency=10, termination_strategy=termination_strategy)"""
@@ -51,7 +51,7 @@
5151
termination_strategy=termination_strategy)"""
5252
"""agent = SimulatedAnnealing(initial_temperature=[1.0, 1.0], cooling_rate=0.9999, tabu_entity_rate=0.2,
5353
mutation_rate_multiplier=None, move_probas=[0, 0.2, 0.2, 0.2, 0.2, 0.2],
54-
compare_to_global=True, migration_frequency=10, termination_strategy=termination_strategy)"""
54+
migration_frequency=10, termination_strategy=termination_strategy)"""
5555

5656
solver = Solver(domain_builder, cotwin_builder, agent,
5757
ParallelizationBackend.Multiprocessing, LoggingLevel.Info,
@@ -61,6 +61,6 @@
6161
domain = domain_builder.build_from_solution(solution)
6262
domain.print_metrics()
6363
domain.print_path()
64-
domain.plot_path()
64+
#domain.plot_path()
6565

6666
print("done")

examples/object_oriented/vrp/scripts/solve_vrp.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333
#file_path = Path(data_dir_path, data_dir_path, "belgium", "basic", "air", "belgium-n1000-k40.vrp") #optimum: ~57.7; first_fit: ~195.3; RoutingModel: from 67.3 to 74 (depends on time)
3434
# multi-depot with timewindows
3535
#file_path = Path(data_dir_path, "belgium", "multidepot-timewindowed", "air", "belgium-tw-d2-n50-k10.vrp") # optimum: ~15.98; first_fit: ~27.89
36-
file_path = Path(data_dir_path, "belgium", "multidepot-timewindowed", "air", "belgium-tw-d5-n500-k20.vrp") # optimum: ~43.3; first_fit: ~124.884
36+
#file_path = Path(data_dir_path, "belgium", "multidepot-timewindowed", "air", "belgium-tw-d5-n500-k20.vrp") # optimum: ~43.3; first_fit: ~124.884
3737
#file_path = Path(data_dir_path, "belgium", "multidepot-timewindowed", "air", "belgium-tw-d8-n1000-k40.vrp") # optimum: ~58.1; first_fit: ~154.565
38-
#file_path = Path(data_dir_path, "belgium", "multidepot-timewindowed", "air", "belgium-tw-d10-n2750-k55.vrp") # optimum: ~111; first_fit: ~380.9
38+
file_path = Path(data_dir_path, "belgium", "multidepot-timewindowed", "air", "belgium-tw-d10-n2750-k55.vrp") # optimum: ~111; first_fit: ~380.9
3939

4040
domain_builder = DomainBuilder(file_path)
4141
cotwin_builder = CotwinBuilder(use_incremental_score_calculator=True, use_greed_init=True)
@@ -46,16 +46,16 @@
4646
#termination_strategy = ScoreLimit(score_to_compare=[0])
4747
agent = TabuSearch(neighbours_count=128, tabu_entity_rate=0.8,
4848
mutation_rate_multiplier=None, move_probas=[0.5, 0.5, 0.0, 0.0, 0.0, 0.0],
49-
compare_to_global=True, migration_frequency=10, termination_strategy=termination_strategy)
49+
migration_frequency=10, termination_strategy=termination_strategy)
5050
"""agent = GeneticAlgorithm(population_size=512, crossover_probability=0.5, p_best_rate=0.2,
5151
tabu_entity_rate=0.0, mutation_rate_multiplier=None, move_probas=[0.5, 0.5, 0.0, 0.0, 0.0, 0.0],
5252
migration_rate=0.00001, migration_frequency=10, termination_strategy=termination_strategy)"""
5353
"""agent = LateAcceptance(late_acceptance_size=32, tabu_entity_rate=0.8,
5454
mutation_rate_multiplier=None, move_probas=[0.5, 0.5, 0.0, 0.0, 0.0, 0.0],
55-
termination_strategy=termination_strategy)"""
55+
compare_to_global_frequency=10, termination_strategy=termination_strategy)"""
5656
"""agent = SimulatedAnnealing(initial_temperature=[1.0, 1.0, 1.0], cooling_rate=0.9999, tabu_entity_rate=0.0,
5757
mutation_rate_multiplier=None, move_probas=[0.5, 0.5, 0.0, 0.0, 0.0, 0.0],
58-
compare_to_global=True, migration_frequency=10, termination_strategy=termination_strategy)"""
58+
migration_frequency=10, termination_strategy=termination_strategy)"""
5959

6060
solver = Solver(domain_builder, cotwin_builder, agent,
6161
ParallelizationBackend.Multiprocessing, LoggingLevel.FreshOnly,
@@ -65,7 +65,7 @@
6565
domain = domain_builder.build_from_solution(solution)
6666
domain.print_metrics()
6767
domain.print_paths()
68-
domain.plot_paths()
68+
#domain.plot_paths()
6969

7070

7171
"""
@@ -99,7 +99,7 @@
9999
termination_strategy = ScoreNoImprovement(time_seconds_limit=15)
100100
agent = TabuSearch(neighbours_count=128, tabu_entity_rate=0.0,
101101
mutation_rate_multiplier=None, move_probas=[0.5, 0.5, 0.0, 0.0, 0.0, 0.0],
102-
compare_to_global=True, migration_frequency=10, termination_strategy=termination_strategy)
102+
migration_frequency=10, termination_strategy=termination_strategy)
103103
solver = Solver(domain_builder, cotwin_builder, agent,
104104
ParallelizationBackend.Multiprocessing, LoggingLevel.FreshOnly,
105105
n_jobs=10, score_precision=[0, 0, 0],

greyjack/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

greyjack/Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "greyjack"
3-
version = "0.1.2"
3+
version = "0.1.3"
44
edition = "2024"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -22,8 +22,8 @@ polars = { version = "0.46.0", features = ["lazy", "ndarray", "serde", "abs"] }
2222
# if you build lib from source code
2323
# uncomment to gain max performance (increases calculation speed about 5-10%,
2424
# but also increases build time ~20x times)
25-
#[profile.release]
26-
#lto = true
27-
#codegen-units = 1
28-
#debug = true
29-
#opt-level = 3
25+
[profile.release]
26+
lto = true
27+
codegen-units = 1
28+
debug = true
29+
opt-level = 3

greyjack/greyjack/agents/GeneticAlgorithm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def __init__(
1111
migration_rate=0.00001, migration_frequency=10, termination_strategy=None,
1212
):
1313

14-
super().__init__(migration_rate, migration_frequency, termination_strategy)
14+
super().__init__(migration_rate, migration_frequency, termination_strategy, compare_to_global_frequency=1)
1515

1616
self.population_size = population_size
1717
self.crossover_probability = crossover_probability

greyjack/greyjack/agents/LateAcceptance.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ def __init__(
1111
mutation_rate_multiplier=None,
1212
move_probas=None,
1313
migration_frequency=999_999_999_999, # probably, better use only comparing with global. Need more researching.
14+
compare_to_global_frequency=10, # too often comparing significally decreases common performance for fast-stepping metaheuristics
1415
termination_strategy=None,
1516
):
1617

17-
super().__init__(1.0, migration_frequency, termination_strategy)
18+
super().__init__(1.0, migration_frequency, termination_strategy, compare_to_global_frequency)
1819

1920
self.population_size = 1
2021
self.late_acceptance_size = late_acceptance_size

greyjack/greyjack/agents/SimulatedAnnealing.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ def __init__(
1212
tabu_entity_rate,
1313
mutation_rate_multiplier=None,
1414
move_probas=None,
15-
compare_to_global=False,
1615
migration_frequency=None,
16+
compare_to_global_frequency=10, # too often comparing significally decreases common performance for fast-stepping metaheuristics
1717
termination_strategy=None,
1818
):
1919

20-
super().__init__(1.0, migration_frequency, termination_strategy)
20+
super().__init__(1.0, migration_frequency, termination_strategy, compare_to_global_frequency)
2121

2222
self.population_size = 1
2323
self.initial_temperature = initial_temperature
@@ -28,7 +28,7 @@ def __init__(
2828

2929
# If true - stucks more often in local minimums, but converges much faster
3030
# may be useful in multiple stages solving
31-
self.is_win_from_comparing_with_global = compare_to_global
31+
self.is_win_from_comparing_with_global = True
3232

3333
def _build_metaheuristic_base(self):
3434
self.score_requester = OOPScoreRequester(self.cotwin)

greyjack/greyjack/agents/TabuSearch.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ def __init__(
1010
tabu_entity_rate,
1111
mutation_rate_multiplier=None,
1212
move_probas=None,
13-
compare_to_global=False,
1413
migration_frequency=None,
14+
compare_to_global_frequency=1, # Tabu is usually not too fast-stepping due to high neighbours_count
1515
termination_strategy=None,
1616
):
1717

18-
super().__init__(1.0, migration_frequency, termination_strategy)
18+
super().__init__(1.0, migration_frequency, termination_strategy, compare_to_global_frequency)
1919

2020
self.population_size = 1
2121
self.neighbours_count = neighbours_count
@@ -25,7 +25,7 @@ def __init__(
2525

2626
# If true - stucks more often in local minimums, but converges much faster
2727
# may be useful in multiple stages solving
28-
self.is_win_from_comparing_with_global = compare_to_global
28+
self.is_win_from_comparing_with_global = True
2929

3030
def _build_metaheuristic_base(self):
3131
self.score_requester = OOPScoreRequester(self.cotwin)

greyjack/greyjack/agents/base/Agent.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
class Agent():
1919

20-
def __init__(self, migration_rate, migration_frequency, termination_strategy):
20+
def __init__(self, migration_rate, migration_frequency, termination_strategy, compare_to_global_frequency):
2121

2222
if termination_strategy is None:
2323
raise Exception("Agent's termination_strategy is None.")
@@ -40,6 +40,8 @@ def __init__(self, migration_rate, migration_frequency, termination_strategy):
4040
self.migration_rate = migration_rate
4141
self.migration_frequency = migration_frequency
4242
self.steps_to_send_updates = migration_frequency
43+
self.compare_to_global_frequency = compare_to_global_frequency
44+
self.steps_to_compare_with_global = compare_to_global_frequency
4345
self.agent_status = "alive"
4446
self.is_last_message_shown = False
4547
self.round_robin_status_dict = {}
@@ -182,12 +184,15 @@ def solve(self):
182184
self.logger.warning(f"Agent: {self.agent_id:4} has successfully terminated work. Now it's just transmitting updates between its neighbours until at least one agent is alive.")
183185
self.is_last_message_shown = True
184186

185-
self._send_candidate_to_master(step_id)
187+
self.steps_to_compare_with_global -= 1
188+
if self.steps_to_compare_with_global <= 0:
189+
self._send_candidate_to_master(step_id)
186190

187-
if self.is_win_from_comparing_with_global or (not self.is_master_received_variables_info):
188-
self._check_global_updates()
189-
if self.is_end:
190-
return
191+
if self.is_win_from_comparing_with_global or (not self.is_master_received_variables_info):
192+
self._check_global_updates()
193+
if self.is_end:
194+
return
195+
self.steps_to_compare_with_global = self.compare_to_global_frequency
191196
except Exception as e:
192197
print(e)
193198
exit(-1)

greyjack/greyjack/score_calculation/score_calculators/IncrementalScoreCalculator.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from greyjack.agents.base.individuals.IndividualSimple import IndividualSimple
77
from greyjack.agents.base.individuals.IndividualHardSoft import IndividualHardSoft
88
from greyjack.agents.base.individuals.IndividualHardMediumSoft import IndividualHardMediumSoft
9+
from greyjack.greyjack import sum_simple_scores, sum_hard_soft_scores, sum_hard_medium_soft_scores
910

1011
class IncrementalScoreCalculator:
1112
def __init__(self):
@@ -17,6 +18,8 @@ def __init__(self):
1718
self.score_type = None
1819
self.score_variant = None
1920
self.is_incremental = True
21+
self.constraints_names_list = None
22+
self.scores_summation_function = None
2023

2124
def add_constraint(self, constraint_name, constraint_function):
2225
self.constraints[constraint_name] = constraint_function
@@ -51,27 +54,21 @@ def get_score(self, planning_entity_dfs, problem_fact_dfs, delta_dfs):
5154
else:
5255
if self.score_variant == ScoreVariants.SimpleScore:
5356
self.score_type = SimpleScore
57+
self.scores_summation_function = sum_simple_scores
5458
if self.score_variant == ScoreVariants.HardSoftScore:
5559
self.score_type = HardSoftScore
60+
self.scores_summation_function = sum_hard_soft_scores
5661
if self.score_variant == ScoreVariants.HardMediumSoftScore:
5762
self.score_type = HardMediumSoftScore
63+
self.scores_summation_function = sum_hard_medium_soft_scores
5864

5965
for prescoring_function in self.prescoring_functions.values():
60-
prescoring_function(planning_entity_dfs, problem_fact_dfs, delta_dfs)
66+
prescoring_function(planning_entity_dfs, problem_fact_dfs)
6167

62-
constraints_names_list = list(self.constraints.keys())
63-
scores_vec = [self.constraints[name](planning_entity_dfs, problem_fact_dfs, delta_dfs) for name in constraints_names_list]
64-
65-
constraints_count = len(scores_vec)
66-
samples_count = len(scores_vec[0]) if scores_vec else 0
67-
scores = []
68-
69-
for j in range(samples_count):
70-
sample_sum_score = self.score_type.get_null_score()
71-
for i in range(constraints_count):
72-
constraint_weight = self.constraint_weights[constraints_names_list[i]]
73-
weighted_score = scores_vec[i][j].mul(constraint_weight)
74-
sample_sum_score = sample_sum_score + weighted_score
75-
scores.append(sample_sum_score)
68+
if self.constraints_names_list is None:
69+
self.constraints_names_list = list(self.constraints.keys())
70+
71+
scores_vec = [self.constraints[name](planning_entity_dfs, problem_fact_dfs, delta_dfs) for name in self.constraints_names_list]
72+
scores = self.scores_summation_function(scores_vec, self.constraint_weights, self.constraints_names_list)
7673

7774
return scores

greyjack/greyjack/score_calculation/score_calculators/PlainScoreCalculator.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from greyjack.agents.base.individuals.IndividualSimple import IndividualSimple
77
from greyjack.agents.base.individuals.IndividualHardSoft import IndividualHardSoft
88
from greyjack.agents.base.individuals.IndividualHardMediumSoft import IndividualHardMediumSoft
9+
from greyjack.greyjack import sum_simple_scores, sum_hard_soft_scores, sum_hard_medium_soft_scores
910

1011
class PlainScoreCalculator:
1112
def __init__(self):
@@ -17,6 +18,8 @@ def __init__(self):
1718
self.score_type = None
1819
self.score_variant = None
1920
self.is_incremental = False
21+
self.constraints_names_list = None
22+
self.scores_summation_function = None
2023

2124
def add_constraint(self, constraint_name, constraint_function):
2225
self.constraints[constraint_name] = constraint_function
@@ -51,27 +54,21 @@ def get_score(self, planning_entity_dfs, problem_fact_dfs):
5154
else:
5255
if self.score_variant == ScoreVariants.SimpleScore:
5356
self.score_type = SimpleScore
57+
self.scores_summation_function = sum_simple_scores
5458
if self.score_variant == ScoreVariants.HardSoftScore:
5559
self.score_type = HardSoftScore
60+
self.scores_summation_function = sum_hard_soft_scores
5661
if self.score_variant == ScoreVariants.HardMediumSoftScore:
5762
self.score_type = HardMediumSoftScore
63+
self.scores_summation_function = sum_hard_medium_soft_scores
5864

5965
for prescoring_function in self.prescoring_functions.values():
6066
prescoring_function(planning_entity_dfs, problem_fact_dfs)
6167

62-
constraints_names_list = list(self.constraints.keys())
63-
scores_vec = [self.constraints[name](planning_entity_dfs, problem_fact_dfs) for name in constraints_names_list]
64-
65-
constraints_count = len(scores_vec)
66-
samples_count = len(scores_vec[0])
67-
scores = []
68-
69-
for j in range(samples_count):
70-
sample_sum_score = self.score_type.get_null_score()
71-
for i in range(constraints_count):
72-
constraint_weight = self.constraint_weights[constraints_names_list[i]]
73-
weighted_score = scores_vec[i][j].mul(constraint_weight)
74-
sample_sum_score = sample_sum_score + weighted_score
75-
scores.append(sample_sum_score)
68+
if self.constraints_names_list is None:
69+
self.constraints_names_list = list(self.constraints.keys())
70+
71+
scores_vec = [self.constraints[name](planning_entity_dfs, problem_fact_dfs) for name in self.constraints_names_list]
72+
scores = self.scores_summation_function(scores_vec, self.constraint_weights, self.constraints_names_list)
7673

7774
return scores

greyjack/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ features = ["pyo3/extension-module"]
77

88
[project]
99
name = "greyjack"
10-
version = "0.1.2"
10+
version = "0.1.3"
1111
requires-python = ">=3.9"
1212
dependencies = [
1313
"dill",

0 commit comments

Comments
 (0)