Skip to content

Commit c525812

Browse files
committed
v0.1.4 Some refactoring, small performance increasing (for fast-stepping metaheuristics)
1 parent 2c4b4bf commit c525812

File tree

10 files changed

+71
-39
lines changed

10 files changed

+71
-39
lines changed

examples/object_oriented/nqueens/scripts/solve_nqueens.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#termination_strategy = TimeSpentLimit(time_seconds_limit=60)
2828
#termination_strategy = ScoreNoImprovement(time_seconds_limit=15)
2929
termination_strategy = ScoreLimit(score_to_compare=[0])
30-
agent = TabuSearch(neighbours_count=20, tabu_entity_rate=0.0,
30+
agent = TabuSearch(neighbours_count=128, tabu_entity_rate=0.0,
3131
mutation_rate_multiplier=None, move_probas=[0, 1, 0, 0, 0, 0],
3232
migration_frequency=10, termination_strategy=termination_strategy)
3333
"""agent = GeneticAlgorithm(population_size=128, crossover_probability=0.5, p_best_rate=0.05,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# This is an example of the N-Queens problem, which is a classic combinatorial problem.
2+
# The problem is to place N queens on an N x N chessboard so that no two queens attack each other.
3+
#
4+
# We show how to model the problem as a MIP and solve it using highspy.
5+
# Using numpy can simplify the construction of the constraints (i.e., diagonal).
6+
7+
import highspy
8+
import numpy as np
9+
from datetime import datetime
10+
11+
N = 64
12+
h = highspy.Highs()
13+
h.silent()
14+
15+
x = h.addBinaries(N, N)
16+
17+
h.addConstrs(x.sum(axis=0) == 1) # each row has exactly one queen
18+
h.addConstrs(x.sum(axis=1) == 1) # each col has exactly one queen
19+
20+
y = np.fliplr(x)
21+
h.addConstrs(x.diagonal(k).sum() <= 1 for k in range(-N + 1, N)) # each diagonal has at most one queen
22+
h.addConstrs(y.diagonal(k).sum() <= 1 for k in range(-N + 1, N)) # each 'reverse' diagonal has at most one queen
23+
24+
start_time = datetime.now()
25+
h.solve()
26+
solving_time = datetime.now() - start_time
27+
28+
sol = h.vals(x)
29+
print('Queens:')
30+
for i in range(N):
31+
print(''.join('Q' if sol[i, j] > 0.5 else '*' for j in range(N)))
32+
33+
print("Solving time: {}", solving_time)

examples/object_oriented/nqueens/scripts/solve_nqueens_ortools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def main(board_size: int) -> None:
7171

7272
if __name__ == "__main__":
7373
# By default, solve the 8x8 problem.
74-
size = 1024
74+
size = 256
7575
if len(sys.argv) > 1:
7676
size = int(sys.argv[1])
7777
main(size)

examples/object_oriented/vrp/scripts/solve_vrp.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,22 @@
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)
4242

4343
#termination_strategy = StepsLimit(step_count_limit=1000)
44-
termination_strategy = TimeSpentLimit(time_seconds_limit=60)
45-
#termination_strategy = ScoreNoImprovement(time_seconds_limit=15)
44+
#termination_strategy = TimeSpentLimit(time_seconds_limit=60)
45+
termination_strategy = ScoreNoImprovement(time_seconds_limit=15)
4646
#termination_strategy = ScoreLimit(score_to_compare=[0])
47-
agent = TabuSearch(neighbours_count=128, tabu_entity_rate=0.8,
47+
agent = TabuSearch(neighbours_count=1280, tabu_entity_rate=0.8,
4848
mutation_rate_multiplier=None, move_probas=[0.5, 0.5, 0.0, 0.0, 0.0, 0.0],
4949
migration_frequency=10, termination_strategy=termination_strategy)
50-
"""agent = GeneticAlgorithm(population_size=512, crossover_probability=0.5, p_best_rate=0.2,
51-
tabu_entity_rate=0.0, mutation_rate_multiplier=None, move_probas=[0.5, 0.5, 0.0, 0.0, 0.0, 0.0],
50+
"""agent = GeneticAlgorithm(population_size=128, crossover_probability=0.5, p_best_rate=0.05,
51+
tabu_entity_rate=0.8, 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],

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: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "greyjack"
3-
version = "0.1.3"
3+
version = "0.1.4"
44
edition = "2024"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -20,10 +20,10 @@ chrono = "0.4.39"
2020
polars = { version = "0.46.0", features = ["lazy", "ndarray", "serde", "abs"] }
2121

2222
# if you build lib from source code
23-
# uncomment to gain max performance (increases calculation speed about 5-10%,
23+
# uncomment to gain max performance (increases calculation speed about ~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/Solver.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
import orjson
2+
import pickle
33
import time
44
import random
55
import uuid
@@ -255,7 +255,7 @@ def _setup_agents(self):
255255
def receive_agent_publication(self):
256256

257257
agent_publication = self.master_to_agents_subscriber_socket.recv()
258-
agent_publication = orjson.loads(agent_publication)
258+
agent_publication = pickle.loads(agent_publication)
259259
agent_id = agent_publication["agent_id"]
260260
agent_status = agent_publication["status"]
261261
local_step = agent_publication["step"]
@@ -276,7 +276,7 @@ def send_global_update(self, is_end):
276276
else:
277277
master_publication = [None, self.is_variables_info_received, is_end]
278278

279-
master_publication = orjson.dumps(master_publication)
279+
master_publication = pickle.dumps(master_publication)
280280
self.master_to_agents_publisher_socket.send( master_publication )
281281

282282
def update_global_top_solution(self):

greyjack/greyjack/agents/base/Agent.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import random
44
import logging
55
import math
6-
import orjson
6+
import pickle
77
import time
88
import zmq
99
import sys
@@ -143,7 +143,7 @@ def solve(self):
143143
self.steps_to_send_updates = self.migration_frequency
144144
self.termination_strategy.update( self )
145145
except Exception as e:
146-
print(e)
146+
self.logger.error(f"{e}")
147147
exit(-1)
148148

149149
step_id = 0
@@ -157,7 +157,7 @@ def solve(self):
157157
else:
158158
self._step_plain()
159159
except Exception as e:
160-
print(e)
160+
self.logger.error(f"{e}")
161161
exit(-1)
162162

163163
try:
@@ -194,7 +194,7 @@ def solve(self):
194194
return
195195
self.steps_to_compare_with_global = self.compare_to_global_frequency
196196
except Exception as e:
197-
print(e)
197+
self.logger.error(f"{e}")
198198
exit(-1)
199199

200200
def _init_population(self):
@@ -260,7 +260,7 @@ def _send_receive_updates_universal(self):
260260

261261
def _send_updates_universal(self):
262262

263-
ready_to_send_request = orjson.dumps( "ready to send updates" )
263+
ready_to_send_request = pickle.dumps( "ready to send updates" )
264264
self.agent_to_agent_socket_sender.connect(self.next_agent_address)
265265
self.agent_to_agent_socket_sender.send( ready_to_send_request )
266266
#request_count_limit = 3
@@ -296,15 +296,15 @@ def _send_updates_universal(self):
296296
else:
297297
request["history_archive"] = None
298298

299-
request_serialized = orjson.dumps(request)
299+
request_serialized = pickle.dumps(request)
300300
try:
301301
self.agent_to_agent_socket_sender.connect(self.next_agent_address)
302302
self.agent_to_agent_socket_sender.send( request_serialized )
303303
reply = self.agent_to_agent_socket_sender.recv()
304304
except Exception as e:
305305
self.logger.error(e)
306306
return
307-
reply = orjson.loads( reply )
307+
reply = pickle.loads( reply )
308308

309309
return reply
310310

@@ -315,19 +315,19 @@ def _get_updates_universal(self):
315315
except Exception as e:
316316
self.logger.error(e)
317317
self.logger.error("failed to receive update")
318-
self.agent_to_agent_socket_receiver.send(orjson.dumps("Failed to receive updates"))
318+
self.agent_to_agent_socket_receiver.send(pickle.dumps("Failed to receive updates"))
319319
return
320-
self.agent_to_agent_socket_receiver.send(orjson.dumps("{}".format(self.agent_id)))
320+
self.agent_to_agent_socket_receiver.send(pickle.dumps("{}".format(self.agent_id)))
321321

322322
try:
323323
updates_reply = self.agent_to_agent_socket_receiver.recv()
324324
except Exception as e:
325325
self.logger.error(e)
326326
self.logger.error("failed to receive")
327-
self.agent_to_agent_socket_receiver.send(orjson.dumps("Failed to receive updates"))
327+
self.agent_to_agent_socket_receiver.send(pickle.dumps("Failed to receive updates"))
328328
return
329-
self.agent_to_agent_socket_receiver.send(orjson.dumps("Successfully received updates"))
330-
updates_reply = orjson.loads( updates_reply )
329+
self.agent_to_agent_socket_receiver.send(pickle.dumps("Successfully received updates"))
330+
updates_reply = pickle.loads( updates_reply )
331331

332332
if self.metaheuristic_base.metaheuristic_name == "LSHADE":
333333
history_migrant = updates_reply["history_archive"]
@@ -465,7 +465,7 @@ def _send_candidate_to_master_universal(self, step_id):
465465
else:
466466
agent_publication["variable_names"] = self.score_requester.variables_manager.get_variables_names_vec()
467467
agent_publication["discrete_ids"] = self.score_requester.variables_manager.discrete_ids
468-
agent_publication = orjson.dumps( agent_publication )
468+
agent_publication = pickle.dumps( agent_publication )
469469
self.agent_to_master_socket_publisher.send( agent_publication )
470470

471471
def _check_global_updates(self):
@@ -475,7 +475,7 @@ def _check_global_updates(self):
475475

476476
def _check_global_updates_universal(self):
477477
master_publication = self.agent_to_master_subscriber_socket.recv()
478-
master_publication = orjson.loads(master_publication)
478+
master_publication = pickle.loads(master_publication)
479479

480480
if self.is_win_from_comparing_with_global:
481481
global_top_individual = master_publication[0]

greyjack/greyjack/agents/base/individuals/Individual.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ def get_related_individual_type(score_variant):
2121

2222
def get_related_individual_type_by_value(score_variant_value):
2323

24-
if score_variant_value == ScoreVariants.SimpleScore.value:
24+
if score_variant_value == ScoreVariants.SimpleScore:
2525
return IndividualSimple
26-
if score_variant_value == ScoreVariants.HardSoftScore.value:
26+
if score_variant_value == ScoreVariants.HardSoftScore:
2727
return IndividualHardSoft
28-
if score_variant_value == ScoreVariants.HardMediumSoftScore.value:
28+
if score_variant_value == ScoreVariants.HardMediumSoftScore:
2929
return IndividualHardMediumSoft
3030

3131
raise Exception("score_variant unrecognized")

greyjack/pyproject.toml

Lines changed: 1 addition & 2 deletions
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.3"
10+
version = "0.1.4"
1111
requires-python = ">=3.9"
1212
dependencies = [
1313
"dill",
@@ -16,7 +16,6 @@ dependencies = [
1616
"mypy-extensions",
1717
"mypy-protobuf",
1818
"numpy",
19-
"orjson",
2019
"pathos",
2120
"polars",
2221
"pyarrow",

0 commit comments

Comments
 (0)