From 4001551c9ca2ce68baf06afb74fc8dd546675372 Mon Sep 17 00:00:00 2001 From: raj_mathe Date: Tue, 21 Jun 2022 17:25:39 +0200 Subject: [PATCH] =?UTF-8?q?woche12=20>=20master:=20code=20py=20-=20leere?= =?UTF-8?q?=20EPs=20f=C3=BCr=20walks=20+=20genetic=20hinzugef=C3=BCgt=20(s?= =?UTF-8?q?tubs)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../python/src/algorithms/genetic/__init__.py | 16 ++++ .../src/algorithms/genetic/algorithms.py | 38 ++++++++ code/python/src/algorithms/genetic/display.py | 30 +++++++ .../src/algorithms/random_walk/__init__.py | 18 ++++ .../src/algorithms/random_walk/algorithms.py | 75 ++++++++++++++++ .../src/algorithms/random_walk/display.py | 30 +++++++ code/python/src/api.py | 4 + code/python/src/endpoints/__init__.py | 4 + .../src/endpoints/ep_algorithm_euklid.py | 2 +- .../src/endpoints/ep_algorithm_genetic.py | 34 +++++++ .../src/endpoints/ep_algorithm_pollard_rho.py | 2 +- .../src/endpoints/ep_algorithm_random_walk.py | 59 ++++++++++++ .../src/endpoints/ep_algorithm_rucksack.py | 2 +- code/python/src/models/config/commands.py | 4 + code/python/src/models/genetic/__init__.py | 0 .../python/src/models/random_walk/__init__.py | 16 ++++ .../src/models/random_walk/landscape.py | 90 +++++++++++++++++++ code/python/src/thirdparty/misc.py | 4 +- 18 files changed, 424 insertions(+), 4 deletions(-) create mode 100644 code/python/src/algorithms/genetic/__init__.py create mode 100644 code/python/src/algorithms/genetic/algorithms.py create mode 100644 code/python/src/algorithms/genetic/display.py create mode 100644 code/python/src/algorithms/random_walk/__init__.py create mode 100644 code/python/src/algorithms/random_walk/algorithms.py create mode 100644 code/python/src/algorithms/random_walk/display.py create mode 100644 code/python/src/endpoints/ep_algorithm_genetic.py create mode 100644 code/python/src/endpoints/ep_algorithm_random_walk.py create mode 100644 code/python/src/models/genetic/__init__.py create mode 100644 code/python/src/models/random_walk/__init__.py create mode 100644 code/python/src/models/random_walk/landscape.py diff --git a/code/python/src/algorithms/genetic/__init__.py b/code/python/src/algorithms/genetic/__init__.py new file mode 100644 index 0000000..b859d69 --- /dev/null +++ b/code/python/src/algorithms/genetic/__init__.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.algorithms.genetic.algorithms import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +__all__ = [ + 'genetic_algorithm', +]; diff --git a/code/python/src/algorithms/genetic/algorithms.py b/code/python/src/algorithms/genetic/algorithms.py new file mode 100644 index 0000000..5c360b7 --- /dev/null +++ b/code/python/src/algorithms/genetic/algorithms.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.thirdparty.types import *; +from src.thirdparty.maths import *; + +from models.generated.config import *; +from src.core.log import *; +from src.core.utils import *; +from src.models.genetic import *; +from src.algorithms.genetic.display import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +__all__ = [ + 'genetic_algorithm', +]; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHOD genetic algorithm +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def genetic_algorithm( + individual1: List[str], + individual2: List[str], + verbose: bool, +): + ''' + Führt den genetischen Algorithmus auf 2 Individuen aus. + ''' + log_warn('Noch nicht implementiert!'); + return; diff --git a/code/python/src/algorithms/genetic/display.py b/code/python/src/algorithms/genetic/display.py new file mode 100644 index 0000000..1057a07 --- /dev/null +++ b/code/python/src/algorithms/genetic/display.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.thirdparty.code import *; +from src.thirdparty.maths import *; +from src.thirdparty.types import *; + +from src.core.log import *; +from src.models.genetic import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +__all__ = [ + 'display_table', +]; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHOD display table +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def display_table( +) -> str: + log_warn('Noch nicht implementiert!'); + return ''; diff --git a/code/python/src/algorithms/random_walk/__init__.py b/code/python/src/algorithms/random_walk/__init__.py new file mode 100644 index 0000000..fef358a --- /dev/null +++ b/code/python/src/algorithms/random_walk/__init__.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.algorithms.random_walk.algorithms import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +__all__ = [ + 'adaptive_walk_algorithm', + 'gradient_walk_algorithm', + 'metropolis_walk_algorithm', +]; diff --git a/code/python/src/algorithms/random_walk/algorithms.py b/code/python/src/algorithms/random_walk/algorithms.py new file mode 100644 index 0000000..001b5c4 --- /dev/null +++ b/code/python/src/algorithms/random_walk/algorithms.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.thirdparty.types import *; +from src.thirdparty.maths import *; + +from models.generated.config import *; +from models.generated.commands import *; +from src.core.log import *; +from src.core.utils import *; +from src.models.random_walk import *; +from src.algorithms.random_walk.display import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +__all__ = [ + 'adaptive_walk_algorithm', + 'gradient_walk_algorithm', + 'metropolis_walk_algorithm', +]; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHOD adaptive walk +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def adaptive_walk_algorithm( + landscape: Landscape, + r: float, + optimise: EnumOptimiseMode, + verbose: bool, +): + ''' + Führt den Adapative-Walk Algorithmus aus, um ein lokales Minimum zu bestimmen. + ''' + log_warn('Noch nicht implementiert!'); + return; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHOD gradient walk +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def gradient_walk_algorithm( + landscape: Landscape, + r: float, + optimise: EnumOptimiseMode, + verbose: bool, +): + ''' + Führt den Gradient-Descent (bzw. Ascent) Algorithmus aus, um ein lokales Minimum zu bestimmen. + ''' + log_warn('Noch nicht implementiert!'); + return; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHOD metropolis walk +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def metropolis_walk_algorithm( + landscape: Landscape, + r: float, + annealing: bool, + optimise: EnumOptimiseMode, + verbose: bool, +): + ''' + Führt den Metropolis-Walk Algorithmus aus, um ein lokales Minimum zu bestimmen. + ''' + log_warn('Noch nicht implementiert!'); + return; diff --git a/code/python/src/algorithms/random_walk/display.py b/code/python/src/algorithms/random_walk/display.py new file mode 100644 index 0000000..a929937 --- /dev/null +++ b/code/python/src/algorithms/random_walk/display.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.thirdparty.code import *; +from src.thirdparty.maths import *; +from src.thirdparty.types import *; + +from src.core.log import *; +from src.models.random_walk import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +__all__ = [ + 'display_table', +]; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHOD display table +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def display_table( +) -> str: + log_warn('Noch nicht implementiert!'); + return ''; diff --git a/code/python/src/api.py b/code/python/src/api.py index 6d3239c..984e489 100644 --- a/code/python/src/api.py +++ b/code/python/src/api.py @@ -40,6 +40,10 @@ def run_command(command: Command) -> Result[CallResult, CallError]: return endpoint_hirschberg(command); elif isinstance(command, CommandRucksack): return endpoint_rucksack(command); + elif isinstance(command, CommandRandomWalk): + return endpoint_random_walk(command); + elif isinstance(command, CommandGenetic): + return endpoint_genetic(command); elif isinstance(command, CommandEuklid): return endpoint_euklid(command); elif isinstance(command, CommandPollard): diff --git a/code/python/src/endpoints/__init__.py b/code/python/src/endpoints/__init__.py index cfb4e27..1bb1e79 100644 --- a/code/python/src/endpoints/__init__.py +++ b/code/python/src/endpoints/__init__.py @@ -9,6 +9,8 @@ from src.endpoints.ep_algorithm_hirschberg import *; from src.endpoints.ep_algorithm_tarjan import *; from src.endpoints.ep_algorithm_tsp import *; from src.endpoints.ep_algorithm_rucksack import *; +from src.endpoints.ep_algorithm_genetic import *; +from src.endpoints.ep_algorithm_random_walk import *; from src.endpoints.ep_algorithm_euklid import *; from src.endpoints.ep_algorithm_pollard_rho import *; @@ -21,6 +23,8 @@ __all__ = [ 'endpoint_tarjan', 'endpoint_tsp', 'endpoint_rucksack', + 'endpoint_random_walk', + 'endpoint_genetic', 'endpoint_euklid', 'endpoint_pollard_rho', ]; diff --git a/code/python/src/endpoints/ep_algorithm_euklid.py b/code/python/src/endpoints/ep_algorithm_euklid.py index 79aece4..2794710 100644 --- a/code/python/src/endpoints/ep_algorithm_euklid.py +++ b/code/python/src/endpoints/ep_algorithm_euklid.py @@ -29,6 +29,6 @@ def endpoint_euklid(command: CommandEuklid) -> Result[CallResult, CallError]: result = euklidean_algorithm( a = command.numbers[0].__root__, b = command.numbers[1].__root__, - verbose = config.OPTIONS.tsp.verbose, + verbose = config.OPTIONS.euklid.verbose, ); return Ok(CallResult(action_taken=True, message=result)); diff --git a/code/python/src/endpoints/ep_algorithm_genetic.py b/code/python/src/endpoints/ep_algorithm_genetic.py new file mode 100644 index 0000000..bac82d1 --- /dev/null +++ b/code/python/src/endpoints/ep_algorithm_genetic.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.thirdparty.code import *; + +from models.generated.commands import *; +from src.core.calls import *; +from src.setup import config; +from src.algorithms.genetic import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +__all__ = [ + 'endpoint_genetic', +]; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ENDPOINT +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +@run_safely() +def endpoint_genetic(command: CommandGenetic) -> Result[CallResult, CallError]: + result = genetic_algorithm( + individual1 = command.population[0], + individual2 = command.population[1], + verbose = config.OPTIONS.genetic.verbose, + ); + return Ok(CallResult(action_taken=True, message=result)); diff --git a/code/python/src/endpoints/ep_algorithm_pollard_rho.py b/code/python/src/endpoints/ep_algorithm_pollard_rho.py index 2d23363..4674c9c 100644 --- a/code/python/src/endpoints/ep_algorithm_pollard_rho.py +++ b/code/python/src/endpoints/ep_algorithm_pollard_rho.py @@ -29,6 +29,6 @@ def endpoint_pollard_rho(command: CommandPollard) -> Result[CallResult, CallErro result = pollard_rho_algorithm( n = command.number, x_init = command.x_init, - verbose = config.OPTIONS.tsp.verbose, + verbose = config.OPTIONS.pollard_rho.verbose, ); return Ok(CallResult(action_taken=True, message=result)); diff --git a/code/python/src/endpoints/ep_algorithm_random_walk.py b/code/python/src/endpoints/ep_algorithm_random_walk.py new file mode 100644 index 0000000..37b5953 --- /dev/null +++ b/code/python/src/endpoints/ep_algorithm_random_walk.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.thirdparty.code import *; + +from models.generated.commands import *; +from src.core.calls import *; +from src.setup import config; +from src.models.random_walk import *; +from src.algorithms.random_walk import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +__all__ = [ + 'endpoint_random_walk', +]; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ENDPOINT +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +@run_safely() +def endpoint_random_walk(command: CommandRandomWalk) -> Result[CallResult, CallError]: + landscape = Landscape( + values = command.landscape.values, + metric = command.landscape.neighbourhoods.metric, + ); + match command.algorithm: + case EnumWalkMode.adaptive: + result = adaptive_walk_algorithm( + landscape = landscape, + r = command.landscape.neighbourhoods.radius, + optimise = command.optimise, + verbose = config.OPTIONS.random_walk.verbose + ); + case EnumWalkMode.gradient: + result = gradient_walk_algorithm( + landscape = landscape, + r = command.landscape.neighbourhoods.radius, + optimise = command.optimise, + verbose = config.OPTIONS.random_walk.verbose + ); + case EnumWalkMode.metropolis: + result = metropolis_walk_algorithm( + landscape = landscape, + r = command.landscape.neighbourhoods.radius, + annealing = command.annealing, + optimise = command.optimise, + verbose = config.OPTIONS.random_walk.verbose + ); + case _ as alg: + raise Exception(f'No algorithm implemented for {alg.value}.'); + return Ok(CallResult(action_taken=True, message=result)); diff --git a/code/python/src/endpoints/ep_algorithm_rucksack.py b/code/python/src/endpoints/ep_algorithm_rucksack.py index 0fa4793..9f800c1 100644 --- a/code/python/src/endpoints/ep_algorithm_rucksack.py +++ b/code/python/src/endpoints/ep_algorithm_rucksack.py @@ -50,5 +50,5 @@ def endpoint_rucksack(command: CommandRucksack) -> Result[CallResult, CallError] verbose = config.OPTIONS.rucksack.verbose, ); case _ as alg: - raise Exception(f'No algorithm implemented for {alg.value}.') + raise Exception(f'No algorithm implemented for {alg.value}.'); return Ok(CallResult(action_taken=True, message=result)); diff --git a/code/python/src/models/config/commands.py b/code/python/src/models/config/commands.py index 39e0b4a..9d1eb51 100644 --- a/code/python/src/models/config/commands.py +++ b/code/python/src/models/config/commands.py @@ -44,6 +44,10 @@ def interpret_command(command: Command) -> Command: return CommandHirschberg(**command.dict()); case EnumAlgorithmNames.rucksack: return CommandRucksack(**command.dict()); + case EnumAlgorithmNames.random_walk: + return CommandRandomWalk(**command.dict()); + case EnumAlgorithmNames.genetic: + return CommandGenetic(**command.dict()); case EnumAlgorithmNames.euklid: return CommandEuklid(**command.dict()); case EnumAlgorithmNames.pollard_rho: diff --git a/code/python/src/models/genetic/__init__.py b/code/python/src/models/genetic/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/code/python/src/models/random_walk/__init__.py b/code/python/src/models/random_walk/__init__.py new file mode 100644 index 0000000..a5bdd2f --- /dev/null +++ b/code/python/src/models/random_walk/__init__.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.models.random_walk.landscape import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +__all__ = [ + 'Landscape', +]; diff --git a/code/python/src/models/random_walk/landscape.py b/code/python/src/models/random_walk/landscape.py new file mode 100644 index 0000000..131a941 --- /dev/null +++ b/code/python/src/models/random_walk/landscape.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from __future__ import annotations; + +from src.thirdparty.maths import *; +from src.thirdparty.misc import *; +from src.thirdparty.types import *; + +from models.generated.commands import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +__all__ = [ + 'Landscape', +]; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHOD fitness function -> Array +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class Landscape(): + _fct: np.ndarray; + _metric: EnumLandscapeMetric; + _radius: float; + + def __init__( + self, + values: DataTypeLandscapeValues, + metric: EnumLandscapeMetric = EnumLandscapeMetric.maximum, + ): + self._fct = convert_to_nparray(values); + self._metric = metric; + return; + + @property + def shape(self) -> tuple: + return self._fct.shape; + + @property + def dim(self) -> int: + return len(self._fct.shape); + + def fitness(self, *x: int) -> float: + return self._fct[x]; + + def neighbourhood(self, *x: int, r: float, strict: bool = False) -> List[tuple]: + sides = [ + [ xx - j for j in range(1,r+1) if xx - j in range(s) ] + + ([ xx ] if xx in range(s) else []) + + [ xx + j for j in range(1,r+1) if xx + j in range(s) ] + for xx, s in zip(x, self.shape) + ]; + match self._metric: + case EnumLandscapeMetric.maximum: + umg = list(itertools_product(*sides)); + case EnumLandscapeMetric.manhattan: + umg = [ + (*x[:i], xx, *x[(i+1):]) + for i, side in enumerate(sides) + for xx in side + ]; + case _: + umg = [ x ]; + if strict: + umg = [ p for p in umg if p != x ]; + return umg; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# AUXILIARY METHODS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def convert_to_array(values: DataTypeLandscapeValues) -> list: + return [ + x if isinstance(x, float) else convert_to_array(x) + for x in values.__root__ + ]; + +def convert_to_nparray(values: DataTypeLandscapeValues) -> np.ndarray: + try: + list_of_lists = convert_to_array(values); + return np.asarray(list_of_lists, dtype=float); + except: + raise ValueError('Could not convert to a d-dimensional array! Ensure that the dimensions are consistent.'); diff --git a/code/python/src/thirdparty/misc.py b/code/python/src/thirdparty/misc.py index 8476b32..1aa4dd4 100644 --- a/code/python/src/thirdparty/misc.py +++ b/code/python/src/thirdparty/misc.py @@ -7,6 +7,7 @@ from datetime import datetime; from datetime import timedelta; +from itertools import product as itertools_product; import lorem; import re; from textwrap import dedent; @@ -16,9 +17,10 @@ from textwrap import dedent; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __all__ = [ - 'lorem', 'datetime', 'timedelta', + 'itertools_product', + 'lorem', 're', 'dedent', ];