ads1_2021/code/algorithms/search/interpol.py

70 lines
2.4 KiB
Python
Raw Normal View History

#!/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, p: int, **_):
value = L[p] if p >= 0 else None;
assert value == x, 'Der Algorithmus hat versagt.';
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ALGORITHM interpolation
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='Interpolationssuchalgorithmus', outputnames='p', 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.
2021-10-24 13:18:39 +02:00
Annahme: L sei aufsteigend sortiert.
2021-10-24 13:18:39 +02:00
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('Interpolant 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 L[p+1], L[p+2], ..., L[v] fortsetzen.');
return InterpolationSearch(L=L, x=x, u=p+1, v=v);
else: # x < L[p]
logDebug('Suche in L[u], L[u+1], ..., L[p-1] 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;