master > master: code - python code umgezogen
This commit is contained in:
0
code/python/src/algorithms/sum/__init__.py
Normal file
0
code/python/src/algorithms/sum/__init__.py
Normal file
9
code/python/src/algorithms/sum/exports.py
Normal file
9
code/python/src/algorithms/sum/exports.py
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# EXPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.algorithms.sum.maxsubsum import MaxSubSum;
|
||||
from src.algorithms.sum.maxsubsum import MaxSubSumDC;
|
||||
179
code/python/src/algorithms/sum/maxsubsum.py
Normal file
179
code/python/src/algorithms/sum/maxsubsum.py
Normal file
@@ -0,0 +1,179 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.maths import *;
|
||||
from src.local.typing import *;
|
||||
|
||||
from src.core.log import *;
|
||||
from src.algorithms.methods import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES/CONSTANTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# CHECKS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
def preChecks(L: List[int], **_):
|
||||
assert len(L) > 0, 'Liste darf nicht leer sein.';
|
||||
return;
|
||||
|
||||
def postChecks(L: List[int], **_):
|
||||
# TODO
|
||||
return;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ALGORITHM max sub sum
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@algorithmInfos(name='MaxSubSum (Maximale Teilsumme)', outputnames=('maxSum', 'index_from', 'index_to'), checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
|
||||
def MaxSubSum(L: List[float]) -> Tuple[float, int, int]:
|
||||
'''
|
||||
Inputs: L = Liste von Zahlen
|
||||
|
||||
Outputs:
|
||||
- maxSum = Wert der maximalen Summe einer Teilliste aufeinanderfolgender Elemente
|
||||
- u, v = Indexes so dass die Teilliste [L[u], L[u+1], ..., L[v]] die maximale Summe aufweist
|
||||
'''
|
||||
maxSum: float = 0;
|
||||
u: int = 0;
|
||||
v: int = -1;
|
||||
for i in range(len(L)):
|
||||
## Bestimme maximale Teilsumme der linken Rände der Liste ab Index i:
|
||||
maxSum_, _, k = lRandSum(L[i:]);
|
||||
if maxSum_ > maxSum:
|
||||
k += i; # NOTE: muss wegen Offset kompensieren
|
||||
maxSum, u, v = maxSum_, i, k;
|
||||
logDebug('max Teilsumme aktualisiert: Summe L[i] von i={u} .. {v} = {value}'.format(u = u, v = v, value = maxSum));
|
||||
return maxSum, u, v;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ALGORITHM max sub sum (D & C)
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@algorithmInfos(name='MaxSubSum (Maximale Teilsumme mit D & C)', outputnames=('maxSum', 'index_from', 'index_to'), checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
|
||||
def MaxSubSumDC(L: List[float]) -> Tuple[float, int, int]:
|
||||
'''
|
||||
Inputs: L = Liste von Zahlen
|
||||
|
||||
Outputs:
|
||||
- maxSum = Wert der maximalen Summe einer Teilliste aufeinanderfolgender Elemente
|
||||
- u, v = Indexes so dass die Teilliste [L[u], L[u+1], ..., L[v]] die maximale Summe aufweist
|
||||
'''
|
||||
maxSum = 0;
|
||||
u = 0;
|
||||
v = -1;
|
||||
if len(L) == 1:
|
||||
## wenn Liste aus 1 Element besteht, nicht teilen:
|
||||
if L[0] > maxSum:
|
||||
v = 0;
|
||||
maxSum = L[0];
|
||||
else:
|
||||
u = math.ceil(len(L)/2);
|
||||
Ll = L[:u];
|
||||
Lr = L[u:];
|
||||
## berechnet maximale Teilsumme der linken Hälfte:
|
||||
maxSum1, u1, v1 = MaxSubSumDC(L=Ll);
|
||||
## berechnet maximale Teilsumme der rechten Hälfte:
|
||||
maxSum2, u2, v2 = MaxSubSumDC(L=Lr);
|
||||
u2, v2 = u2 + len(Ll), v2 + len(Ll); # offsets kompensieren
|
||||
## berechnet maximale Teilsumme mit Überschneidung zw. den Hälften:
|
||||
maxSum3, u3, v3 = lrRandSum(Ll=Ll, Lr=Lr);
|
||||
## bestimme Maximum der 3 Möglichkeiten:
|
||||
maxSum = max(maxSum1, maxSum2, maxSum3);
|
||||
if maxSum == maxSum1:
|
||||
maxSum, u, v = maxSum1, u1, v1;
|
||||
logDebug('max Teilsumme kommt in linker Partition vor: Summe L[i] von i={i} .. {j} = {value}'.format(L = L, i = u, j = v, value = maxSum));
|
||||
elif maxSum == maxSum3:
|
||||
maxSum, u, v = maxSum3, u3, v3;
|
||||
logDebug('max Teilsumme kommt in Überschneidung vor: Summe L[i] von i={i} .. {j} = {value}'.format(L = L, i = u, j = v, value = maxSum));
|
||||
else: # elif maxSum == maxSum2:
|
||||
maxSum, u, v = maxSum2, u2, v2;
|
||||
logDebug('max Teilsumme kommt in rechter Partition vor: Summe L[i] von i={i} .. {j} = {value}'.format(L = L, i = u, j = v, value = maxSum));
|
||||
return maxSum, u, v;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# AUXILIARY METHODS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
def lrRandSum(Ll: List[float], Lr: List[float]) -> Tuple[float, int, int]:
|
||||
'''
|
||||
Bestimmt maximale Teilsumme einer Teiliste einer Liste,
|
||||
wobei die Liste in zwei Intervalle partitioniert ist
|
||||
und die Teilliste beide überschneidet.
|
||||
|
||||
Inputs: Ll, Lr = eine Partition einer Liste von Zahlen in zwei Intervalle
|
||||
Outputs: maxSum, u=0, v
|
||||
'''
|
||||
maxSumL, u, _ = rRandSum(L=Ll);
|
||||
maxSumR, _, v = lRandSum(L=Lr);
|
||||
maxSum = maxSumL + maxSumR;
|
||||
v += len(Ll) # offsets kompensieren
|
||||
return maxSum, u, v;
|
||||
|
||||
def lRandSum(L: List[float]) -> Tuple[float, int, int]:
|
||||
'''
|
||||
Bestimmt maximale Teilsumme aller nicht leeren linken Segmente einer Liste.
|
||||
|
||||
Inputs: L = Liste von Zahlen
|
||||
Outputs: maxSum, u(=0), v
|
||||
'''
|
||||
n = len(L);
|
||||
## berechne kumulative Summen (vorwärts)
|
||||
AddToCounter(n);
|
||||
total = L[0];
|
||||
maxSum = total;
|
||||
u = 0;
|
||||
v = 0;
|
||||
for i in range(1, n):
|
||||
total += L[i];
|
||||
if total > maxSum:
|
||||
v = i;
|
||||
maxSum = total;
|
||||
return maxSum, 0, v;
|
||||
|
||||
def rRandSum(L: List[float]) -> Tuple[float, int, int]:
|
||||
'''
|
||||
Bestimmt maximale Teilsumme aller nicht leeren rechten Segmente einer Liste.
|
||||
|
||||
Inputs: L = Liste von Zahlen
|
||||
Outputs: maxSum, u, v(=len(L)-1)
|
||||
'''
|
||||
n = len(L);
|
||||
## berechne kumulative Summen (rückwärts)
|
||||
AddToCounter(n);
|
||||
total = L[n-1];
|
||||
maxSum = total;
|
||||
u = n-1;
|
||||
v = n-1;
|
||||
for i in range(0, n-1)[::-1]:
|
||||
total += L[i];
|
||||
if total > maxSum:
|
||||
u = i;
|
||||
maxSum = total;
|
||||
return maxSum, u, v;
|
||||
|
||||
# Sei N ∈ ℕ⁺
|
||||
# Sei p so, dass 2^p ≤ N < 2^{p+1},
|
||||
# Also p = floor(log₂(N)).
|
||||
# Setze
|
||||
# B(i,d) := {k < N | bit(k, i) = d}
|
||||
# für i ∈ {0, 1, ..., p-1}
|
||||
# und setze
|
||||
# 𝒜 = {B(i,d) : i ∈ {0, 1, ..., p-1}, d ∈ {0,1}}.
|
||||
# Seien k1, k2 ∈ N mit k1 ≠ k2.
|
||||
# Dann existiert i ∈ {0, 1, ..., p-1},
|
||||
# so dass
|
||||
# d := bit(k1, i) ≠ bit(k2, i).
|
||||
# Also
|
||||
# k1 ∈ B(i, d) ∌ k2.
|
||||
# Darum erfüllt 𝒜 die erwünschte Eigenschaft.
|
||||
# Es gilt
|
||||
# |𝒜| = 2p = 2·floor(log₂(N)) ∈ O(log(N)).
|
||||
Reference in New Issue
Block a user