73 lines
2.5 KiB
Python
73 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
|
||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
# IMPORTS
|
||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
from local.maths import *;
|
||
from local.typing import *;
|
||
|
||
from code.core.log import *;
|
||
from code.algorithms.methods import *;
|
||
|
||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
# GLOBAL VARIABLES/CONSTANTS
|
||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
#
|
||
|
||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
# CHECKS
|
||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
def preChecks(L: List[int], **_):
|
||
assert L == sorted(L), 'Ungültiger Input: L muss aufsteigend sortiert sein!';
|
||
return;
|
||
|
||
def postChecks(L: List[int], x: int, index: int, **_):
|
||
if x in L:
|
||
assert index >= 0, 'Der Algorithmus sollte nicht -1 zurückgeben.';
|
||
assert L[index] == x, 'Der Algorithmus hat den falschen Index bestimmt.';
|
||
else:
|
||
assert index == -1, 'Der Algorithmus sollte -1 zurückgeben.';
|
||
return;
|
||
|
||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
# ALGORITHM interpolation
|
||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
@algorithmInfos(name='Interpolationssuchalgorithmus', outputnames='index', checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
|
||
def InterpolationSearch(L: List[int], x: int, u: int, v: int) -> int:
|
||
'''
|
||
Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval.
|
||
|
||
Annahme: L sei aufsteigend sortiert.
|
||
|
||
Outputs: Position von x in L, sonst −1 wenn x nicht in L.
|
||
'''
|
||
if not(L[u] <= x and x <= L[v]):
|
||
logDebug('Element kann sich nicht in der Liste befinden!')
|
||
return -1;
|
||
p = getSuchposition(L=L, x=x, u=u, v=v);
|
||
logDebug('Interpolante von x in (u, v)={uv} ist p = {p}.'.format(uv=(u, v), p=p));
|
||
if L[p] == x:
|
||
logDebug('x in Position p gefunden');
|
||
return p;
|
||
elif x > L[p]:
|
||
logDebug('Suche in rechter Hälfte fortsetzen.');
|
||
return InterpolationSearch(L=L, x=x, u=p+1, v=v);
|
||
else: # x < L[p]
|
||
logDebug('Suche in linker Hälfte fortsetzen.');
|
||
return InterpolationSearch(L=L, x=x, u=u, v=p-1);
|
||
|
||
def getSuchposition(L: List[int], x: int, u: int, v: int) -> int:
|
||
'''
|
||
Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval.
|
||
Outputs: Interpolierte Position, um Suchinterval ausgeglichen aufzuteilen.
|
||
'''
|
||
AddToCounter();
|
||
r = (x - L[u])/(L[v]-L[u]);
|
||
p = math.floor(u + r*(v-u))
|
||
return p;
|