#!/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. 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('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;