master > master: src go - algorithmen + display methoden hinzugefügt
This commit is contained in:
169
code/golang/internal/algorithms/sum/maxsubsum/maxsubsum.go
Normal file
169
code/golang/internal/algorithms/sum/maxsubsum/maxsubsum.go
Normal file
@@ -0,0 +1,169 @@
|
||||
package maxsubsum
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"ads/internal/core/logging"
|
||||
"ads/internal/core/metrics"
|
||||
"ads/internal/core/utils"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* GLOBAL VARIABLES/CONSTANTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
//
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* ALGORITHM max sub sum
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
func MaxSubSum(L []int) (int, int, int) {
|
||||
maxSum := 0
|
||||
u := 0
|
||||
v := -1
|
||||
for i := 0; i < len(L); i++ {
|
||||
// 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
|
||||
logging.LogDebug(fmt.Sprintf("max Teilsumme aktualisiert: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum))
|
||||
}
|
||||
}
|
||||
return maxSum, u, v
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* ALGORITHM max sub sum (D & C)
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
func MaxSubSumDC(L []int) (int, int, int) {
|
||||
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 = utils.Ceil(float64(len(L)) / 2)
|
||||
Ll := L[:u]
|
||||
Lr := L[u:]
|
||||
// berechnet maximale Teilsumme der linken Hälfte:
|
||||
maxSum1, u1, v1 := MaxSubSumDC(Ll)
|
||||
// berechnet maximale Teilsumme der rechten Hälfte:
|
||||
maxSum2, u2, v2 := MaxSubSumDC(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, Lr)
|
||||
// bestimme Maximum der 3 Möglichkeiten:
|
||||
maxSum = utils.MaxInt(maxSum1, maxSum2, maxSum3)
|
||||
if maxSum == maxSum1 {
|
||||
maxSum, u, v = maxSum1, u1, v1
|
||||
logging.LogDebug(fmt.Sprintf("max Teilsumme kommt in linker Partition vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum))
|
||||
} else if maxSum == maxSum3 {
|
||||
maxSum, u, v = maxSum3, u3, v3
|
||||
logging.LogDebug(fmt.Sprintf("max Teilsumme kommt in Überschneidung vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum))
|
||||
} else { // } else if maxSum == maxSum2 {
|
||||
maxSum, u, v = maxSum2, u2, v2
|
||||
logging.LogDebug(fmt.Sprintf("max Teilsumme kommt in rechter Partition vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum))
|
||||
}
|
||||
}
|
||||
return maxSum, u, v
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* AUXILIARY METHODS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
func lrRandSum(Ll []int, Lr []int) (int, int, int) {
|
||||
maxSumL, u, _ := rRandSum(Ll)
|
||||
maxSumR, _, v := lRandSum(Lr)
|
||||
maxSum := maxSumL + maxSumR
|
||||
v += len(Ll) // offsets kompensieren
|
||||
return maxSum, u, v
|
||||
}
|
||||
|
||||
/*
|
||||
Bestimmt maximale Teilsumme aller nicht leeren linken Segmente einer Liste.
|
||||
|
||||
Inputs: L = Liste von Zahlen
|
||||
|
||||
Outputs: maxSum, u(=0), v
|
||||
*/
|
||||
func lRandSum(L []int) (int, int, int) {
|
||||
n := len(L)
|
||||
// berechne kumulative Summen (vorwärts)
|
||||
metrics.AddTimeCost(n)
|
||||
total := L[0]
|
||||
maxSum := total
|
||||
u := 0
|
||||
v := 0
|
||||
for i := 0; i < n; i++ {
|
||||
total += L[i]
|
||||
if total > maxSum {
|
||||
v = i
|
||||
maxSum = total
|
||||
}
|
||||
}
|
||||
return maxSum, u, v
|
||||
}
|
||||
|
||||
/*
|
||||
Bestimmt maximale Teilsumme aller nicht leeren rechten Segmente einer Liste.
|
||||
|
||||
Inputs: L = Liste von Zahlen
|
||||
|
||||
Outputs: maxSum, u, v(=len(L)-1)
|
||||
*/
|
||||
func rRandSum(L []int) (int, int, int) {
|
||||
n := len(L)
|
||||
// berechne kumulative Summen (rückwärts)
|
||||
metrics.AddTimeCost(n)
|
||||
total := L[n-1]
|
||||
maxSum := total
|
||||
u := n - 1
|
||||
v := n - 1
|
||||
for i := n - 2; i >= 0; i-- {
|
||||
total += L[i]
|
||||
if total > maxSum {
|
||||
u = i
|
||||
maxSum = total
|
||||
}
|
||||
}
|
||||
return maxSum, u, v
|
||||
}
|
||||
136
code/golang/internal/algorithms/sum/maxsubsum/maxsubsum_fancy.go
Normal file
136
code/golang/internal/algorithms/sum/maxsubsum/maxsubsum_fancy.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package maxsubsum
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"ads/internal/core/metrics"
|
||||
"ads/internal/setup"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* GLOBAL VARIABLES/CONSTANTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
//
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* CHECKS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func preChecks(L []int, _ ...interface{}) error {
|
||||
if !(len(L) > 0) {
|
||||
return fmt.Errorf("Liste darf nicht leer sein.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func postChecks(L []int, _ ...interface{}) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHOD Algorithm + Display
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func FancyMaxSubSum(input_L []int) (int, int, int, error) {
|
||||
var name = "MaxSubSum (Maximale Teilsumme)"
|
||||
var inputs = map[string]interface{}{
|
||||
"L": input_L,
|
||||
}
|
||||
var outputs map[string]interface{}
|
||||
var (
|
||||
output_maxSum int
|
||||
output_indexFrom int
|
||||
output_indexTo int
|
||||
)
|
||||
var err error
|
||||
|
||||
do_once := true
|
||||
for do_once {
|
||||
do_once = false
|
||||
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||
metrics.RestartMetrics()
|
||||
|
||||
// Prechecks:
|
||||
err = preChecks(input_L)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
// Ausführung des Algorithmus:
|
||||
output_maxSum, output_indexFrom, output_indexTo = MaxSubSum(input_L)
|
||||
outputs = map[string]interface{}{
|
||||
"maxSum": output_maxSum,
|
||||
"index_from": output_indexFrom,
|
||||
"index_to": output_indexTo,
|
||||
}
|
||||
|
||||
// Letzte Messages:
|
||||
setup.DisplayMetrics()
|
||||
setup.DisplayEndOfAlgorithm(outputs)
|
||||
|
||||
// Postchecks:
|
||||
err = postChecks(input_L, output_maxSum, output_indexFrom, output_indexTo)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return output_maxSum, output_indexFrom, output_indexTo, err
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* ALGORITHM max sub sum (D & C)
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func FancyMaxSubSumDC(input_L []int) (int, int, int, error) {
|
||||
var name = "MaxSubSum (Maximale Teilsumme mit D & C)"
|
||||
var inputs = map[string]interface{}{
|
||||
"L": input_L,
|
||||
}
|
||||
var outputs map[string]interface{}
|
||||
var (
|
||||
output_maxSum int
|
||||
output_indexFrom int
|
||||
output_indexTo int
|
||||
)
|
||||
var err error
|
||||
|
||||
do_once := true
|
||||
for do_once {
|
||||
do_once = false
|
||||
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||
metrics.RestartMetrics()
|
||||
|
||||
// Prechecks:
|
||||
err = preChecks(input_L)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
// Ausführung des Algorithmus:
|
||||
output_maxSum, output_indexFrom, output_indexTo = MaxSubSumDC(input_L)
|
||||
outputs = map[string]interface{}{
|
||||
"maxSum": output_maxSum,
|
||||
"index_from": output_indexFrom,
|
||||
"index_to": output_indexTo,
|
||||
}
|
||||
|
||||
// Letzte Messages:
|
||||
setup.DisplayMetrics()
|
||||
setup.DisplayEndOfAlgorithm(outputs)
|
||||
|
||||
// Postchecks:
|
||||
err = postChecks(input_L, output_maxSum, output_indexFrom, output_indexTo)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return output_maxSum, output_indexFrom, output_indexTo, err
|
||||
}
|
||||
Reference in New Issue
Block a user