Compare commits
No commits in common. "96bb225978eb40865290c295a731c8e776261c9e" and "5e92cd1fd4401e46bad3f62558c4fcb937d3fb15" have entirely different histories.
96bb225978
...
5e92cd1fd4
2
.gitignore
vendored
2
.gitignore
vendored
@ -15,6 +15,8 @@
|
|||||||
################################################################
|
################################################################
|
||||||
|
|
||||||
!/notes
|
!/notes
|
||||||
|
!/notes/glossar.md
|
||||||
|
!/notes/quellen.md
|
||||||
|
|
||||||
!/protocol
|
!/protocol
|
||||||
!/protocol/README.md
|
!/protocol/README.md
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
import math;
|
import math;
|
||||||
import numpy as np;
|
|
||||||
import random;
|
import random;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -15,6 +14,5 @@ import random;
|
|||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'math',
|
'math',
|
||||||
'np',
|
|
||||||
'random',
|
'random',
|
||||||
];
|
];
|
||||||
|
@ -17,7 +17,6 @@ from typing import Tuple;
|
|||||||
from typing import Type;
|
from typing import Type;
|
||||||
from typing import TypeVar;
|
from typing import TypeVar;
|
||||||
from typing import Union;
|
from typing import Union;
|
||||||
from nptyping import NDArray;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# EXPORTS
|
# EXPORTS
|
||||||
@ -35,5 +34,4 @@ __all__ = [
|
|||||||
'Type',
|
'Type',
|
||||||
'TypeVar',
|
'TypeVar',
|
||||||
'Union',
|
'Union',
|
||||||
'NDArray',
|
|
||||||
];
|
];
|
||||||
|
@ -12,10 +12,8 @@ os.chdir(os.path.join(os.path.dirname(__file__), '..'));
|
|||||||
sys.path.insert(0, os.getcwd());
|
sys.path.insert(0, os.getcwd());
|
||||||
|
|
||||||
from src.core.log import *;
|
from src.core.log import *;
|
||||||
from src.local.maths import *;
|
|
||||||
from src.graphs.graph import *;
|
from src.graphs.graph import *;
|
||||||
from src.graphs.tarjan import *;
|
from src.graphs.tarjan import *;
|
||||||
from src.travel.naive import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# GLOBAL CONSTANTS/VARIABLES
|
# GLOBAL CONSTANTS/VARIABLES
|
||||||
@ -28,17 +26,28 @@ from src.travel.naive import *;
|
|||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
def enter():
|
def enter():
|
||||||
## Beispiel aus Seminarblatt 8
|
## Beispiel aus Seminarblatt 1
|
||||||
tsp_naive_algorithm(
|
nodes = [1,2,3,4,5,6,7,8];
|
||||||
dist = np.asarray([
|
edges = [
|
||||||
[0, 7, 2, 5],
|
(1,2),
|
||||||
[7, 0, 5, 6],
|
(1,3),
|
||||||
[2, 5, 0, 5],
|
(2,4),
|
||||||
[2, 7, 4, 0],
|
(2,5),
|
||||||
], dtype=float),
|
(3,5),
|
||||||
optimise=max,
|
(3,6),
|
||||||
verbose=True,
|
(3,8),
|
||||||
);
|
(4,5),
|
||||||
|
(4,7),
|
||||||
|
(5,1),
|
||||||
|
(5,8),
|
||||||
|
(6,8),
|
||||||
|
(7,8),
|
||||||
|
(8,6),
|
||||||
|
];
|
||||||
|
G = Graph(nodes=nodes, edges=edges);
|
||||||
|
components = tarjan_algorithm(G, debug=True);
|
||||||
|
for component in components:
|
||||||
|
log_debug(component);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from __future__ import annotations;
|
|
||||||
from src.local.typing import *;
|
|
||||||
from src.local.maths import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'tsp_naive_algorithm',
|
|
||||||
];
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# METHOD tsp_naive_algorithm
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
def tsp_naive_algorithm(
|
|
||||||
dist: NDArray[(Any, Any), float],
|
|
||||||
optimise = min,
|
|
||||||
verbose: bool = False,
|
|
||||||
) -> tuple[float, list[list[int]]]:
|
|
||||||
m, n = dist.shape[:2];
|
|
||||||
assert m == n;
|
|
||||||
memory: Dict[tuple[int, tuple], tuple[float, list[list[int]]]] = dict();
|
|
||||||
|
|
||||||
def g(i: int, S: list[int]) -> tuple[float, list[list[int]]]:
|
|
||||||
# wenn g bereits für den Input definiert ist, gib diesen Wert zurück:
|
|
||||||
if (i, tuple(S)) not in memory.keys():
|
|
||||||
if len(S) == 0:
|
|
||||||
paths = [[i]] if i == 0 else [[i, 0]];
|
|
||||||
memory[(i, tuple(S))] = (dist[i,0], paths);
|
|
||||||
else:
|
|
||||||
values_and_paths = [ (j, *g(j, (*S[:index], *S[(index+1):]))) for index, j in enumerate(S) ];
|
|
||||||
# berechne d(i,j) + g(j, S \ {i}) for each j in S:
|
|
||||||
values_and_paths = [ (j, dist[i,j] + value, paths) for j, value, paths in values_and_paths];
|
|
||||||
value = optimise([value for _, value, _ in values_and_paths]);
|
|
||||||
paths = [];
|
|
||||||
for j, value_, paths_ in values_and_paths:
|
|
||||||
if value_ == value:
|
|
||||||
paths += [ [i, *path] for path in paths_ ];
|
|
||||||
memory[(i, tuple(S))] = (value, paths);
|
|
||||||
return memory[(i, tuple(S))];
|
|
||||||
|
|
||||||
# berechne g(0, {1,2,...,n-1}):
|
|
||||||
optimal_wert = g(0, [i for i in range(1,n)]);
|
|
||||||
|
|
||||||
if verbose:
|
|
||||||
display_computation(n, memory);
|
|
||||||
|
|
||||||
return optimal_wert, [];
|
|
||||||
|
|
||||||
def display_computation(n: int, memory: Dict[tuple[int, tuple], tuple[float, list[list[int]]]]):
|
|
||||||
keys = sorted(memory.keys(), key=lambda key: (len(key[1]), key[0], key[1]));
|
|
||||||
for k in range(0,n):
|
|
||||||
print(f'\x1b[4;1m|S| = {k}:\x1b[0m');
|
|
||||||
for (i, S) in keys:
|
|
||||||
if len(S) != k:
|
|
||||||
continue;
|
|
||||||
value, paths = memory[(i, S)];
|
|
||||||
print(f'g({i}, {list(S)}) = {value}');
|
|
||||||
if len(paths) == 1:
|
|
||||||
print(f'optimal path: {" -> ".join(map(str, paths[0]))}');
|
|
||||||
else:
|
|
||||||
print('optimal paths:');
|
|
||||||
for path in paths:
|
|
||||||
print(f'* {" -> ".join(map(str, path))}');
|
|
||||||
print('');
|
|
||||||
return;
|
|
@ -6,8 +6,17 @@
|
|||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from unittest import TestCase;
|
from unittest import TestCase;
|
||||||
|
from pytest import mark;
|
||||||
from pytest import fixture;
|
from pytest import fixture;
|
||||||
|
|
||||||
|
from tests.core.log import *;
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# CONSTANTS
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# FIXTURES
|
# FIXTURES
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -15,11 +24,3 @@ from pytest import fixture;
|
|||||||
@fixture(scope='module')
|
@fixture(scope='module')
|
||||||
def test():
|
def test():
|
||||||
return TestCase();
|
return TestCase();
|
||||||
|
|
||||||
@fixture(scope='module')
|
|
||||||
def debug():
|
|
||||||
def log(*lines: str):
|
|
||||||
with open('logs/debug.log', 'a') as fp:
|
|
||||||
for line in lines:
|
|
||||||
print(line, end='\n', file=fp);
|
|
||||||
return log;
|
|
||||||
|
17
code/python/tests/core/log.py
Normal file
17
code/python/tests/core/log.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# IMPORTS
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# METHODS - logging
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
def log(*lines: str):
|
||||||
|
with open('logs/debug.log', 'a') as fp:
|
||||||
|
for line in lines:
|
||||||
|
print(line, end='\n', file=fp);
|
@ -9,6 +9,8 @@ from unittest import TestCase;
|
|||||||
from pytest import mark;
|
from pytest import mark;
|
||||||
from pytest import fixture;
|
from pytest import fixture;
|
||||||
|
|
||||||
|
from tests.core.log import *;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# CONSTANTS
|
# CONSTANTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
import pytest;
|
from contextlib import nullcontext as does_not_raise
|
||||||
|
from collections import Counter;
|
||||||
from pytest import mark;
|
from pytest import mark;
|
||||||
from pytest import fixture;
|
from pytest import fixture;
|
||||||
from pytest import lazy_fixture;
|
from pytest import lazy_fixture;
|
||||||
from unittest import TestCase;
|
from unittest import TestCase;
|
||||||
from unittest.mock import patch;
|
|
||||||
|
|
||||||
from src.local.typing import *;
|
from src.local.typing import *;
|
||||||
from src.graphs.graph import *;
|
from src.graphs.graph import *;
|
||||||
@ -73,13 +73,6 @@ def test_tarjan(test, G, expected):
|
|||||||
components = tarjan_algorithm(G, False);
|
components = tarjan_algorithm(G, False);
|
||||||
assert_components_eq(test, components, expected);
|
assert_components_eq(test, components, expected);
|
||||||
|
|
||||||
@patch(f'{__name__}.tarjan_algorithm', lambda *_: [])
|
|
||||||
@mark.parametrize(('G', 'expected'), [ (lazy_fixture('graph1'), [[1], [3], [2,4]])])
|
|
||||||
@mark.usefixtures('test')
|
|
||||||
def test_failable_tarjan(test, G, expected):
|
|
||||||
with pytest.raises(AssertionError):
|
|
||||||
test_tarjan(test, G, expected);
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# AUXILIARY METHODS
|
# AUXILIARY METHODS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
24
notes/.gitignore
vendored
24
notes/.gitignore
vendored
@ -1,24 +0,0 @@
|
|||||||
*
|
|
||||||
!/.gitignore
|
|
||||||
|
|
||||||
################################################################
|
|
||||||
# MAIN FOLDER
|
|
||||||
################################################################
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
################################################################
|
|
||||||
# PROJECT FILES
|
|
||||||
################################################################
|
|
||||||
|
|
||||||
!/glossar.md
|
|
||||||
!/quellen.md
|
|
||||||
!/notes.tex
|
|
||||||
!/notes.pdf
|
|
||||||
!/woche*.pdf
|
|
||||||
|
|
||||||
################################################################
|
|
||||||
# Git Keep
|
|
||||||
################################################################
|
|
||||||
|
|
||||||
!/**/.gitkeep
|
|
Loading…
x
Reference in New Issue
Block a user