master > master: code py - models + config implementiert
This commit is contained in:
		
							parent
							
								
									67f6caf2d5
								
							
						
					
					
						commit
						0523c68100
					
				
							
								
								
									
										6
									
								
								code/python/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								code/python/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -22,12 +22,16 @@ | ||||
| !/src/**/*.py | ||||
| !/main.py | ||||
| 
 | ||||
| !/models | ||||
| !/models/*-schema.yaml | ||||
| !/models/README.md | ||||
| 
 | ||||
| !/tests | ||||
| !/tests/**/ | ||||
| !/tests/**/*.py | ||||
| 
 | ||||
| !/assets | ||||
| !/assets/**/ | ||||
| !/assets/*.yaml | ||||
| 
 | ||||
| !/dist | ||||
| !/dist/VERSION | ||||
|  | ||||
| @ -12,7 +12,7 @@ die Methoden mit Daten ausprobieren. | ||||
| 1. Der Python-Compiler **`^3.10.*`** wird benötigt. | ||||
| 2. Es ist auch empfehlenswert, **`justfile`** zu installieren (siehe <https://github.com/casey/just#installation>). | ||||
| 
 | ||||
| ## Setup -> Test -> Run ## | ||||
| ## Build -> Test -> Run ## | ||||
| 
 | ||||
| In einem IDE in dem Repo zu diesem Ordner navigieren. | ||||
| </br> | ||||
| @ -23,7 +23,7 @@ Wer das **justfile**-Tool hat: | ||||
| # Zeige alle Befehle: | ||||
| just | ||||
| # Zur Installation der Requirements (nur nach Änderungen): | ||||
| just setup; | ||||
| just build; | ||||
| # Zur Ausführung der unit tests: | ||||
| just tests; | ||||
| # Zur Ausführung des Programms | ||||
| @ -43,3 +43,9 @@ python3 main.py | ||||
| Auf Windows verwendet man `py -3` od. `py -310` statt `python3`. | ||||
| 
 | ||||
| Man kann auch mit einem guten Editor/IDE die Tests einzeln ausführen. | ||||
| 
 | ||||
| ## Testfälle durch Config-Datei ## | ||||
| 
 | ||||
| Statt den Code immer anfassen zu müssen, kann man Fälle für die verschiedenen Algorithmen | ||||
| in der **[./assets/commands](assets/commands.yaml)** erfassen und (mittels `just run`) | ||||
| das Programm ausführen. | ||||
|  | ||||
							
								
								
									
										33
									
								
								code/python/assets/commands.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								code/python/assets/commands.yaml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| ## Beispiel für Seminarwoche 9 (Blatt 8) | ||||
| - name: TSP | ||||
|   dist: | ||||
|     - [0, 7, 4, 3] | ||||
|     - [7, 0, 5, 6] | ||||
|     - [2, 5, 0, 5] | ||||
|     - [2, 7, 4, 0] | ||||
|   optimise: MIN | ||||
|   verbose: true | ||||
| ## Beispiele für Seminarwoche 10 (Blatt 9) | ||||
| - &command_hirschberg | ||||
|   name: HIRSCHBERG | ||||
|   once: true | ||||
|   verbose: | ||||
|     - COSTS | ||||
|     - MOVES | ||||
|   # show: | ||||
|   #   # - ATOMS | ||||
|   #   - TREE | ||||
|   word1: 'happily ever after' | ||||
|   word2: 'apples' | ||||
| - <<: *command_hirschberg | ||||
|   word1: 'ANSTRENGEN' | ||||
|   word2: 'ANSPANNEN' | ||||
| - <<: *command_hirschberg | ||||
|   word1: 'ACGAAG' | ||||
|   word2: 'AGAT' | ||||
| - <<: *command_hirschberg | ||||
|   word1: 'happily ever, lol' | ||||
|   word2: 'apple' | ||||
| - <<: *command_hirschberg | ||||
|   word1: 'happily' | ||||
|   word2: 'applses' | ||||
							
								
								
									
										8
									
								
								code/python/assets/config.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								code/python/assets/config.yaml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| info: | ||||
|   author: Raj Dahya | ||||
|   title: Algorithmen und Datenstrukturen 2 | ||||
|   description: |- | ||||
|     Ein Code-Projekt, das Algorithmen und Datenstrukturen aus dem Kurs | ||||
|     ADS2 an der Universität Leipzig (Sommersemester 2022) | ||||
|     implementiert. | ||||
| options: {} | ||||
							
								
								
									
										2
									
								
								code/python/dist/VERSION
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								code/python/dist/VERSION
									
									
									
									
										vendored
									
									
								
							| @ -1 +1 @@ | ||||
| 0.0.0 | ||||
| 0.1.0 | ||||
|  | ||||
| @ -11,6 +11,7 @@ _default: | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | ||||
| 
 | ||||
| PYTHON := if os_family() == "windows" { "py -3" } else { "python3" } | ||||
| GEN_MODELS := "datamodel-codegen" | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | ||||
| # Macros
 | ||||
| @ -42,6 +43,19 @@ _docker-build-and-log service: | ||||
| _docker-build-and-interact service container: | ||||
|     @docker compose up --build -d {{service}} && docker attach {{container}} | ||||
| 
 | ||||
| _generate-models path name: | ||||
|     @{{GEN_MODELS}} \
 | ||||
|         --input-file-type openapi \
 | ||||
|         --encoding "UTF-8" \
 | ||||
|         --disable-timestamp \
 | ||||
|         --use-schema-description \
 | ||||
|         --allow-population-by-field-name \
 | ||||
|         --snake-case-field \
 | ||||
|         --strict-nullable \
 | ||||
|         --target-python-version 3.9 \
 | ||||
|         --input {{path}}/{{name}}-schema.yaml \
 | ||||
|         --output {{path}}/generated/{{name}}.py | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | ||||
| # TARGETS
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | ||||
| @ -50,8 +64,16 @@ _docker-build-and-interact service container: | ||||
| # TARGETS: build
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | ||||
| 
 | ||||
| build: | ||||
| build: _build-requirements _build-skip-requirements | ||||
| _build-skip-requirements: build-models | ||||
| _build-requirements: | ||||
|     @{{PYTHON}} -m pip install --disable-pip-version-check -r requirements.txt | ||||
| build-models: _check-system-requirements _build-models-nochecks | ||||
| _build-models-nochecks: | ||||
|     @echo "Generate data models from schemata." | ||||
|     @just _create-folder-if-not-exists "models/generated" | ||||
|     @- just _generate-models "models" "config" | ||||
|     @- just _generate-models "models" "commands" | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | ||||
| # TARGETS: run
 | ||||
| @ -145,3 +167,8 @@ _display-logs: | ||||
| check-system: | ||||
|     @echo "Operating System detected: {{os_family()}}." | ||||
|     @echo "Python command used: {{PYTHON}}." | ||||
| _check-system-requirements: | ||||
|     @if ! ( {{GEN_MODELS}} --help >> /dev/null 2> /dev/null ); then \
 | ||||
|         echo "Command '{{GEN_MODELS}}' did not work. Ensure that the installation of 'datamodel-code-generator' worked and that system paths are set." \
 | ||||
|         exit 1; \
 | ||||
|     fi | ||||
|  | ||||
| @ -6,18 +6,23 @@ | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| import os; | ||||
| import sys; | ||||
| import sys | ||||
| from token import MINUS; | ||||
| 
 | ||||
| os.chdir(os.path.join(os.path.dirname(__file__), '..')); | ||||
| os.chdir(os.path.join(os.path.dirname(__file__))); | ||||
| sys.path.insert(0, os.getcwd()); | ||||
| 
 | ||||
| from src.core.log import *; | ||||
| from src.thirdparty.maths import *; | ||||
| 
 | ||||
| from models.generated.commands import *; | ||||
| from src.core.log import *; | ||||
| from src.setup.config import *; | ||||
| from src.graphs.graph import *; | ||||
| from src.graphs.tarjan import *; | ||||
| from src.travel.naive import *; | ||||
| from src.tsp import *; | ||||
| from src.hirschberg import *; | ||||
| 
 | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # GLOBAL CONSTANTS/VARIABLES | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| @ -29,38 +34,21 @@ from src.hirschberg import *; | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| def enter(): | ||||
|     # ## Beispiel für Seminarwoche 9 (Blatt 8): | ||||
|     # tsp_naive_algorithm( | ||||
|     #     dist = np.asarray([ | ||||
|     #         [0, 7, 4, 3], | ||||
|     #         [7, 0, 5, 6], | ||||
|     #         [2, 5, 0, 5], | ||||
|     #         [2, 7, 4, 0], | ||||
|     #     ], dtype=float), | ||||
|     #     optimise=min, | ||||
|     #     verbose=True, | ||||
|     # ); | ||||
|     ## Beispiel für Seminarwoche 10 (Blatt 9): | ||||
|     hirschberg_algorithm( | ||||
|         # Y = 'ANSPANNEN', | ||||
|         # X = 'ANSTRENGEN', | ||||
|         # Y = 'AGAT', | ||||
|         # X = 'ACGAAG', | ||||
|         Y = 'apples', | ||||
|         X = 'happily ever after', | ||||
|         # Y = 'applses', | ||||
|         # X = 'happily ever, lol', | ||||
|         # Y = 'apple', | ||||
|         # X = 'happily', | ||||
|         # once = True, | ||||
|         # verb = VerboseMode.COSTS, | ||||
|         # verb = VerboseMode.MOVES, | ||||
|         verb = VerboseMode.COSTS_AND_MOVES, | ||||
|         show = [ | ||||
|             # DisplayOptions.ATOMS, | ||||
|             DisplayOptions.TREE, | ||||
|         ], | ||||
|     ); | ||||
|     for command in COMMANDS: | ||||
|         if isinstance(command, CommandTsp): | ||||
|             tsp_algorithm( | ||||
|                 dist = np.asarray(command.dist, dtype=float), | ||||
|                 optimise = min if command.optimise == EnumTspOptimise.min else max, | ||||
|                 verbose = command.verbose, | ||||
|             ); | ||||
|         elif isinstance(command, CommandHirschberg): | ||||
|             hirschberg_algorithm( | ||||
|                 X = command.word1, | ||||
|                 Y = command.word2, | ||||
|                 once = command.once, | ||||
|                 verb = command.verbose, | ||||
|                 show = command.show, | ||||
|             ); | ||||
|     return; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
							
								
								
									
										51
									
								
								code/python/models/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								code/python/models/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | ||||
| #  Models # | ||||
| 
 | ||||
| - In this folder the configuration files for the models of data classes (as `*.yaml`-files) are stored. | ||||
| - These are interpreted by `openapi` to generate the classes for the source code during the `build` phase of the programme. | ||||
| - Once the models are generated, the app configurations are read at run time and interpreted as these models. | ||||
| - Generating instead of manually encoding the classes is safer/more stable as it allows for validation. | ||||
| 
 | ||||
| ## Folder structure ## | ||||
| 
 | ||||
| As per the 3rd point, the `yaml`-file/s for the models (schemata) | ||||
| and the `yaml`-file/s for actual configuration values for the app | ||||
| are to be kept separately. | ||||
| 
 | ||||
| All models are to be stored in [./models](../models/), | ||||
| whereas configuration files are to be stored in [./assets](../assets/). | ||||
| 
 | ||||
| Note that the generated python files are not stored in the repository. | ||||
| When deployed on a server, these are generated as part of the `build`-process. | ||||
| 
 | ||||
| ## Developer notes ## | ||||
| 
 | ||||
| ### Prerequisites ### | ||||
| 
 | ||||
| For the python source code, we currently use: | ||||
| 
 | ||||
| - Python: `v3.10.*` | ||||
| - Modules: | ||||
|   - `datamodel-code-generator==0.12.0` | ||||
| 
 | ||||
| (This is all taken care of during the `build` process.) | ||||
| 
 | ||||
| ### Building the models ### | ||||
| 
 | ||||
| To build the models before run time, use the following command + options: | ||||
| ```bash | ||||
| datamodel-codegen | ||||
|     --input-file-type openapi | ||||
|     --encoding "UTF-8" | ||||
|     --disable-timestamp | ||||
|     --use-schema-description | ||||
|     --snake-case-field | ||||
|     --strict-nullable | ||||
|     --input <path/to/file.yml> | ||||
|     --output <path/to/file.py> | ||||
| ``` | ||||
| (cf. https://pydantic-docs.helpmanual.io/datamodel_code_generator/). | ||||
| 
 | ||||
| Alternatively, call: | ||||
| ``` | ||||
| just build | ||||
| ``` | ||||
							
								
								
									
										140
									
								
								code/python/models/commands-schema.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								code/python/models/commands-schema.yaml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,140 @@ | ||||
| openapi: 3.0.3 | ||||
| info: | ||||
|   version: 0.1.0 | ||||
|   title: Schemata for command instructions | ||||
| servers: [] | ||||
| paths: {} | ||||
| components: | ||||
|   schemas: | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # Commands | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     Commands: | ||||
|       description: |- | ||||
|         List of commands to test algorithms/datastructures. | ||||
|       type: array | ||||
|       items: | ||||
|         $ref: "#/components/schemas/Command" | ||||
|       default: [] | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # Command | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     Command: | ||||
|       description: |- | ||||
|         Instructions for command to call | ||||
|       required: | ||||
|         - name | ||||
|       properties: &ref_command_properties | ||||
|         name: | ||||
|           $ref: '#/components/schemas/EnumAlgorithmNames' | ||||
|       additionalProperties: true | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # Command - Algorithm: Tarjan | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     CommandTarjan: | ||||
|       description: |- | ||||
|         Instructions for execution of Tarjan-Algorithm | ||||
|       type: object | ||||
|       required: | ||||
|         - name | ||||
|       properties: | ||||
|         <<: *ref_command_properties | ||||
|       # required: | ||||
|       # properties: | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # Command - Algorithm: TSP | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     CommandTsp: | ||||
|       description: |- | ||||
|         Instructions for execution of TSP-Algorithm | ||||
|       type: object | ||||
|       required: | ||||
|         - name | ||||
|         - optimise | ||||
|         - dist | ||||
|       properties: | ||||
|         <<: *ref_command_properties | ||||
|         dist: | ||||
|           type: array | ||||
|           items: | ||||
|             type: array | ||||
|             items: | ||||
|               type: number | ||||
|         optimise: | ||||
|           $ref: '#/components/schemas/EnumTSPOptimise' | ||||
|         verbose: | ||||
|           type: boolean | ||||
|           default: false | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # Command - Algorithm: Hirschberg | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     CommandHirschberg: | ||||
|       description: |- | ||||
|         Instructions for execution of Hirschberg-Algorithm | ||||
|       type: object | ||||
|       required: | ||||
|         - name | ||||
|         - horizontal | ||||
|         - vertical | ||||
|       properties: | ||||
|         <<: *ref_command_properties | ||||
|         word1: | ||||
|           description: Word that gets placed vertically in algorithm. | ||||
|           type: string | ||||
|         word2: | ||||
|           description: Word that gets placed horizontally in algorithm | ||||
|           type: string | ||||
|         once: | ||||
|           type: boolean | ||||
|           default: false | ||||
|         verbose: | ||||
|           type: array | ||||
|           items: | ||||
|             $ref: '#/components/schemas/EnumHirschbergVerbosity' | ||||
|           default: [] | ||||
|         show: | ||||
|           type: array | ||||
|           items: | ||||
|             $ref: '#/components/schemas/EnumHirschbergShow' | ||||
|           default: [] | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # Enum Algorithm Names | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     EnumAlgorithmNames: | ||||
|       description: |- | ||||
|         Enumeration of possible algorithm options. | ||||
|       type: string | ||||
|       enum: | ||||
|         - TARJAN | ||||
|         - TSP | ||||
|         - HIRSCHBERG | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # Enum TSP - Optimise Mode | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     EnumTSPOptimise: | ||||
|       description: |- | ||||
|         Enumeration of optimisation options for TSP | ||||
|       type: string | ||||
|       enum: | ||||
|         - MIN | ||||
|         - MAX | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # Enum Hirschberg - Verbosity options | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     EnumHirschbergVerbosity: | ||||
|       description: |- | ||||
|         Enumeration of verbosity options for Hirschberg | ||||
|       type: string | ||||
|       enum: | ||||
|         - COSTS | ||||
|         - MOVES | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # Enum Hirschberg - display options | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     EnumHirschbergShow: | ||||
|       description: |- | ||||
|         Enumeration of verbosity options for Hirschberg | ||||
|       type: string | ||||
|       enum: | ||||
|         - TREE | ||||
|         - ATOMS | ||||
							
								
								
									
										49
									
								
								code/python/models/config-schema.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								code/python/models/config-schema.yaml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| openapi: 3.0.3 | ||||
| info: | ||||
|   version: 0.1.0 | ||||
|   title: Schemata for config models | ||||
| servers: [] | ||||
| paths: {} | ||||
| components: | ||||
|   schemas: | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # Config | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     Config: | ||||
|       descripton: |- | ||||
|         Data model for all parts of the configuration. | ||||
|       type: object | ||||
|       required: | ||||
|         - info | ||||
|         - options | ||||
|         - calls | ||||
|       properties: | ||||
|         info: | ||||
|           $ref: "#/components/schemas/Info" | ||||
|         options: | ||||
|           $ref: "#/components/schemas/AppOptions" | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # Info | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     Info: | ||||
|       description: |- | ||||
|         Contains meta data about project. | ||||
|       type: object | ||||
|       required: | ||||
|         - title | ||||
|         - description | ||||
|         - author | ||||
|       properties: | ||||
|         title: | ||||
|           type: string | ||||
|         description: | ||||
|           type: string | ||||
|         author: | ||||
|           type: string | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     # App Options | ||||
|     # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|     AppOptions: | ||||
|       description: |- | ||||
|         Options pertaining to the rudimentary setup of the app. | ||||
|       type: object | ||||
| @ -1,7 +1,35 @@ | ||||
| pip>=22.0.4 | ||||
| pip>=22.1.2 | ||||
| wheel>=0.37.1 | ||||
| 
 | ||||
| # running | ||||
| anyio>=3.5.0 | ||||
| aiohttp>=3.8.1 | ||||
| asyncio>=3.4.3 | ||||
| codetiming>=1.3.0 | ||||
| 
 | ||||
| # testing + dev | ||||
| coverage[toml]>=6.4 | ||||
| pytest>=7.1.1 | ||||
| pytest-asyncio>=0.18.3 | ||||
| pytest-cov>=3.0.0 | ||||
| pytest-lazy-fixture>=0.6.3 | ||||
| pytest-order>=1.0.1 | ||||
| testfixtures>=6.18.5 | ||||
| 
 | ||||
| # config | ||||
| python-dotenv>=0.2.0 | ||||
| jsonschema>=4.4.0 | ||||
| lazy-load>=0.8.2 | ||||
| pyyaml>=6.0 | ||||
| pydantic>=1.9.0 | ||||
| datamodel-code-generator>=0.12.0 | ||||
| 
 | ||||
| # misc | ||||
| lorem>=0.1.1 | ||||
| safetywrap>=1.5.0 | ||||
| typing>=3.7.4.3 | ||||
| 
 | ||||
| # maths | ||||
| numpy>=1.22.3 | ||||
| pandas>=1.4.1 | ||||
| tabulate>=0.8.9 | ||||
|  | ||||
| @ -15,6 +15,4 @@ from src.hirschberg.display import *; | ||||
| 
 | ||||
| __all__ = [ | ||||
|     'hirschberg_algorithm', | ||||
|     'VerboseMode', | ||||
|     'DisplayOptions', | ||||
| ]; | ||||
|  | ||||
| @ -8,6 +8,7 @@ | ||||
| from src.thirdparty.types import *; | ||||
| from src.thirdparty.maths import *; | ||||
| 
 | ||||
| from models.generated.commands import *; | ||||
| from src.hirschberg.constants import *; | ||||
| from src.hirschberg.display import *; | ||||
| from src.hirschberg.matrix import *; | ||||
| @ -30,8 +31,8 @@ __all__ = [ | ||||
| def simple_algorithm( | ||||
|     X:    str, | ||||
|     Y:    str, | ||||
|     verb: VerboseMode = VerboseMode.NONE, | ||||
|     show: List[DisplayOptions] = [], | ||||
|     verb: List[EnumHirschbergVerbosity] = [], | ||||
|     show: List[EnumHirschbergShow] = [], | ||||
| ) -> Tuple[str, str]: | ||||
|     ''' | ||||
|     Dieser Algorithmus berechnet die Edit-Distanzen + optimale Richtungen ein Mal. | ||||
| @ -40,7 +41,7 @@ def simple_algorithm( | ||||
|     Costs, Moves = compute_cost_matrix(X = '-' + X, Y = '-' + Y); | ||||
|     path = reconstruct_optimal_path(Moves=Moves); | ||||
|     word_x, word_y = reconstruct_words(X = '-' + X, Y = '-' + Y, moves=[Moves[coord] for coord in path], path=path); | ||||
|     if verb != VerboseMode.NONE: | ||||
|     if verb != []: | ||||
|         repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y, verb=verb); | ||||
|         display = word_y + f'\n{"-"*len(word_x)}\n' + word_x; | ||||
|         print(f'\n{repr}\n\n\x1b[1mOptimales Alignment:\x1b[0m\n\n{display}\n'); | ||||
| @ -50,8 +51,8 @@ def hirschberg_algorithm( | ||||
|     X:    str, | ||||
|     Y:    str, | ||||
|     once: bool = False, | ||||
|     verb: VerboseMode = VerboseMode.NONE, | ||||
|     show: List[DisplayOptions] = [], | ||||
|     verb: List[EnumHirschbergVerbosity] = [], | ||||
|     show: List[EnumHirschbergShow] = [], | ||||
| ) -> Tuple[str, str]: | ||||
|     ''' | ||||
|     Der Hirschberg-Algorithmus berechnet nur die Edit-Distanzen (Kostenmatrix) | ||||
| @ -72,8 +73,8 @@ def hirschberg_algorithm( | ||||
|     word_y = align.as_string2(); | ||||
| 
 | ||||
|     # verbose output hier behandeln (irrelevant für Algorithmus): | ||||
|     if verb != VerboseMode.NONE: | ||||
|         if DisplayOptions.TREE in show: | ||||
|     if verb != []: | ||||
|         if EnumHirschbergShow.tree in show: | ||||
|             display = align.astree(braces=True); | ||||
|         else: | ||||
|             display_x = align.as_string1(braces=True); | ||||
| @ -87,8 +88,8 @@ def hirschberg_algorithm_step( | ||||
|     X:     str, | ||||
|     Y:     str, | ||||
|     depth: int = 0, | ||||
|     verb:  VerboseMode = VerboseMode.NONE, | ||||
|     show:  List[DisplayOptions] = [], | ||||
|     verb:  List[EnumHirschbergVerbosity] = [], | ||||
|     show:  List[EnumHirschbergShow] = [], | ||||
| ) -> Alignment: | ||||
|     ''' | ||||
|     Der rekursive Schritt der Hirschberg-Algorithmus teil eines der Wörter in zwei | ||||
| @ -105,7 +106,7 @@ def hirschberg_algorithm_step( | ||||
|         word_x, word_y = reconstruct_words(X = '-' + X, Y = '-' + Y, moves=[Moves[coord] for coord in path], path=path); | ||||
| 
 | ||||
|         # verbose output hier behandeln (irrelevant für Algorithmus): | ||||
|         if verb != VerboseMode.NONE and (DisplayOptions.ATOMS in show): | ||||
|         if verb != [] and (EnumHirschbergShow.atoms in show): | ||||
|             repr = display_cost_matrix(Costs=Costs, path=path, X = '-' + X, Y = '-' + Y, verb=verb); | ||||
|             print(f'\n\x1b[1mRekursionstiefe: {depth}\x1b[0m\n\n{repr}') | ||||
| 
 | ||||
| @ -126,7 +127,7 @@ def hirschberg_algorithm_step( | ||||
|         Costs2, Moves2 = compute_cost_matrix(X = '-' + X2, Y = '-' + Y2); | ||||
| 
 | ||||
|         # verbose output hier behandeln (irrelevant für Algorithmus): | ||||
|         if verb != VerboseMode.NONE: | ||||
|         if verb != []: | ||||
|             path1, path2 = reconstruct_optimal_path_halves(Costs1=Costs1, Costs2=Costs2, Moves1=Moves1, Moves2=Moves2); | ||||
|             repr = display_cost_matrix_halves( | ||||
|                 Costs1 = Costs1, | ||||
|  | ||||
| @ -12,8 +12,6 @@ from src.thirdparty.types import *; | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| __all__ = [ | ||||
|     'VerboseMode', | ||||
|     'DisplayOptions', | ||||
|     'Directions', | ||||
|     'gap_penalty', | ||||
|     'missmatch_penalty', | ||||
| @ -23,16 +21,6 @@ __all__ = [ | ||||
| # ENUMS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| class VerboseMode(Enum): | ||||
|     NONE = -1; | ||||
|     COSTS = 0; | ||||
|     MOVES = 1; | ||||
|     COSTS_AND_MOVES = 2; | ||||
| 
 | ||||
| class DisplayOptions(Enum): | ||||
|     TREE = 0; | ||||
|     ATOMS = 1; | ||||
| 
 | ||||
| class Directions(Enum): | ||||
|     UNSET = -1; | ||||
|     # Prioritäten hier setzen | ||||
|  | ||||
| @ -8,6 +8,7 @@ | ||||
| from src.thirdparty.types import *; | ||||
| from src.thirdparty.maths import *; | ||||
| 
 | ||||
| from models.generated.commands import *; | ||||
| from src.hirschberg.constants import *; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| @ -29,7 +30,7 @@ def represent_cost_matrix( | ||||
|     path: List[Tuple[int, int]], | ||||
|     X: str, | ||||
|     Y: str, | ||||
|     verb: VerboseMode, | ||||
|     verb: List[EnumHirschbergVerbosity], | ||||
|     pad: bool = False, | ||||
| ) -> np.ndarray: # NDArray[(Any, Any), Any]: | ||||
|     m = len(X); # display vertically | ||||
| @ -42,28 +43,27 @@ def represent_cost_matrix( | ||||
|         table = np.full(shape=(3 + m, 3 + n), dtype=object, fill_value=''); | ||||
| 
 | ||||
|     # topmost rows: | ||||
|     table[0, 3:(3+n)] = [str(j) for j in range(n)]; | ||||
|     table[1, 3:(3+n)] = [y for y in Y]; | ||||
|     table[0, 3:(3+n)] = [ f'\x1b[2m{j}\x1b[0m' for j in range(n) ]; | ||||
|     table[1, 3:(3+n)] = [ f'\x1b[1m{y}\x1b[0m' for y in Y ]; | ||||
|     table[2, 3:(3+n)] = '--'; | ||||
|     # leftmost columns: | ||||
|     table[3:(3+m), 0] = [str(i) for i in range(m)]; | ||||
|     table[3:(3+m), 1] = [x for x in X]; | ||||
|     table[3:(3+m), 0] = [ f'\x1b[2m{i}\x1b[0m' for i in range(m) ]; | ||||
|     table[3:(3+m), 1] = [ f'\x1b[1m{x}\x1b[0m' for x in X ]; | ||||
|     table[3:(3+m), 2] = '|'; | ||||
| 
 | ||||
|     if pad: | ||||
|         table[-3, 3:(3+n)] = '--'; | ||||
|         table[3:(3+m), -1] = '|'; | ||||
| 
 | ||||
|     match verb: | ||||
|         case VerboseMode.MOVES: | ||||
|             table[3:(3+m), 3:(3+n)] = '\x1b[2m.\x1b[0m'; | ||||
|     if EnumHirschbergVerbosity.costs in verb: | ||||
|         table[3:(3+m), 3:(3+n)] = Costs.copy(); | ||||
|         if EnumHirschbergVerbosity.moves in verb: | ||||
|             for (i, j) in path: | ||||
|                 table[3 + i, 3 + j] = '\x1b[31;1m*\x1b[0m'; | ||||
|         case VerboseMode.COSTS | VerboseMode.COSTS_AND_MOVES: | ||||
|             table[3:(3+m), 3:(3+n)] = Costs.copy(); | ||||
|             if verb == VerboseMode.COSTS_AND_MOVES: | ||||
|                 for (i, j) in path: | ||||
|                     table[3 + i, 3 + j] = f'\x1b[31;4;1m{table[3 + i, 3 + j]}\x1b[0m'; | ||||
|                 table[3 + i, 3 + j] = f'\x1b[31;4;1m{table[3 + i, 3 + j]}\x1b[0m'; | ||||
|     elif EnumHirschbergVerbosity.moves in verb: | ||||
|         table[3:(3+m), 3:(3+n)] = '\x1b[2m.\x1b[0m'; | ||||
|         for (i, j) in path: | ||||
|             table[3 + i, 3 + j] = '\x1b[31;1m*\x1b[0m'; | ||||
| 
 | ||||
|     return table; | ||||
| 
 | ||||
| @ -72,7 +72,7 @@ def display_cost_matrix( | ||||
|     path: List[Tuple[int, int]], | ||||
|     X: str, | ||||
|     Y: str, | ||||
|     verb: VerboseMode, | ||||
|     verb: EnumHirschbergVerbosity, | ||||
| ) -> str: | ||||
|     ''' | ||||
|     Zeigt Kostenmatrix + optimalen Pfad. | ||||
| @ -99,7 +99,7 @@ def display_cost_matrix_halves( | ||||
|     X2: str, | ||||
|     Y1: str, | ||||
|     Y2: str, | ||||
|     verb: VerboseMode, | ||||
|     verb: EnumHirschbergVerbosity, | ||||
| ) -> str: | ||||
|     ''' | ||||
|     Zeigt Kostenmatrix + optimalen Pfad für Schritt im D & C Hirschberg-Algorithmus | ||||
|  | ||||
							
								
								
									
										61
									
								
								code/python/src/setup/config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								code/python/src/setup/config.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| #!/usr/bin/env python3 | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # IMPORTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| from src.thirdparty.misc import *; | ||||
| from src.thirdparty.config import *; | ||||
| from src.thirdparty.code import *; | ||||
| from src.thirdparty.types import *; | ||||
| 
 | ||||
| from models.generated.config import *; | ||||
| from models.generated.commands import *; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # EXPORTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| __all__ = [ | ||||
|     'INFO', | ||||
|     'OPTIONS', | ||||
|     'COMMANDS', | ||||
| ]; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # CONSTANTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| PATH_ASSETS_CONFIG: str = 'assets/config.yaml'; | ||||
| PATH_ASSETS_COMMANDS: str = 'assets/commands.yaml'; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # LAZY LOADED RESOURCES | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| def load_assets_config(path: str) -> Config: # pragma: no cover | ||||
|     with open(path, 'r') as fp: | ||||
|         assets = yaml_load(fp, Loader=yaml_FullLoader); | ||||
|         assert isinstance(assets, dict); | ||||
|         return Config(**assets); | ||||
| 
 | ||||
| def create_commands(path: str) -> List[Command]: # pragma: no cover | ||||
|     commands = []; | ||||
|     with open(path, 'r') as fp: | ||||
|         assets = yaml_load(fp, Loader=yaml_FullLoader); | ||||
|         for command in assets: | ||||
|             match Command(**command).name: | ||||
|                 case EnumAlgorithmNames.tarjan: | ||||
|                     commands.append(CommandTarjan(**command)); | ||||
|                 case EnumAlgorithmNames.tsp: | ||||
|                     commands.append(CommandTsp(**command)); | ||||
|                 case EnumAlgorithmNames.hirschberg: | ||||
|                     commands.append(CommandHirschberg(**command)); | ||||
|     return commands; | ||||
| 
 | ||||
| # use lazy loaing to ensure that values only loaded (once) when used | ||||
| CONFIG:   Config        = lazy(load_assets_config, path=PATH_ASSETS_CONFIG); | ||||
| INFO:     Info          = lazy(lambda x: x.info, CONFIG); | ||||
| OPTIONS:  AppOptions    = lazy(lambda x: x.options, CONFIG); | ||||
| COMMANDS: List[Command] = lazy(create_commands, path=PATH_ASSETS_COMMANDS); | ||||
							
								
								
									
										43
									
								
								code/python/src/thirdparty/code.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								code/python/src/thirdparty/code.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| #!/usr/bin/env python3 | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # IMPORTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| from functools import wraps; | ||||
| from functools import partial; | ||||
| from dataclasses import dataclass; | ||||
| from dataclasses import field; | ||||
| from dataclasses import Field; | ||||
| from dataclasses import asdict; | ||||
| from dataclasses import MISSING; | ||||
| from itertools import product as itertools_product; | ||||
| # cf. https://github.com/mplanchard/safetywrap | ||||
| from safetywrap import Ok; | ||||
| from safetywrap import Err; | ||||
| from safetywrap import Nothing; | ||||
| from safetywrap import Result; | ||||
| from safetywrap import Option; | ||||
| from safetywrap import Some; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # EXPORTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| __all__ = [ | ||||
|     'partial', | ||||
|     'wraps', | ||||
|     'asdict', | ||||
|     'dataclass', | ||||
|     'field', | ||||
|     'Field', | ||||
|     'MISSING', | ||||
|     'itertools_product', | ||||
|     'Err', | ||||
|     'Nothing', | ||||
|     'Ok', | ||||
|     'Option', | ||||
|     'Result', | ||||
|     'Some', | ||||
| ]; | ||||
							
								
								
									
										16
									
								
								code/python/src/thirdparty/config.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								code/python/src/thirdparty/config.py
									
									
									
									
										vendored
									
									
								
							| @ -6,10 +6,12 @@ | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| import json; | ||||
| import jsonschema; | ||||
| from lazy_load import lazy; | ||||
| from yaml import add_constructor; | ||||
| from yaml import load; | ||||
| from yaml import Loader; | ||||
| from yaml import FullLoader; | ||||
| from yaml import load as yaml_load; | ||||
| from yaml import FullLoader as yaml_FullLoader; | ||||
| from yaml import add_path_resolver as yaml_add_path_resolver; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # EXPORTS | ||||
| @ -17,8 +19,10 @@ from yaml import FullLoader; | ||||
| 
 | ||||
| __all__ = [ | ||||
|     'json', | ||||
|     'jsonschema', | ||||
|     'lazy', | ||||
|     'add_constructor', | ||||
|     'load', | ||||
|     'Loader', | ||||
|     'FullLoader', | ||||
|     'yaml_load', | ||||
|     'yaml_FullLoader', | ||||
|     'yaml_add_path_resolver', | ||||
| ]; | ||||
|  | ||||
							
								
								
									
										16
									
								
								code/python/src/tsp/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								code/python/src/tsp/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| #!/usr/bin/env python3 | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # IMPORTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| from src.tsp.algorithms import *; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # EXPORTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| __all__ = [ | ||||
|     'tsp_algorithm', | ||||
| ]; | ||||
| @ -5,7 +5,6 @@ | ||||
| # IMPORTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| from __future__ import annotations; | ||||
| from src.thirdparty.types import *; | ||||
| from src.thirdparty.maths import *; | ||||
| 
 | ||||
| @ -14,15 +13,15 @@ from src.thirdparty.maths import *; | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| __all__ = [ | ||||
|     'tsp_naive_algorithm', | ||||
|     'tsp_algorithm', | ||||
| ]; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # METHOD tsp_naive_algorithm | ||||
| # METHOD tsp_algorithm | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| def tsp_naive_algorithm( | ||||
|     dist: NDArray[(Any, Any), float], | ||||
| def tsp_algorithm( | ||||
|     dist: np.ndarray, # NDArray[(Any, Any), float], | ||||
|     optimise = min, | ||||
|     verbose: bool = False, | ||||
| ) -> tuple[float, list[list[int]]]: | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user