Clever-Excel-Forum

Normale Version: Intelligentes dividieren
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Seiten: 1 2
Hallo W...,

auch wenn die Daten nur Testdaten sind, halte ich unnötige Mehrkosten von 11% (100.000€ statt 90.000€) für relevant.
Insbesondere da nach meiner Erfahrung in der "Required Volume" meisten schon viele Sicherheitszuschläge eingerechnet sind.

Wenn auch eine VBA-Lösung (UDF= User Defined Function) erlaubt ist, bitte sehr.
Das Programm berechnet die minimalen Kosten aus allen möglichen Kombinationen.

Mit deinem Zahlenbeispiele weicht das optimale Ergebnis nur selten von den Ergebnissen der Formeln ab. Das kann aber bei anderen Zahlen auch sehr häufig sein.


Code:
Option Explicit
Dim intAnzT As Integer
Dim intAkt() As Integer
Dim intOpt() As Integer
Dim lngAktWert As Long
Dim lngOptWert As Long
Dim varListe() As Variant
Const intMaxE As Integer = 3

Public Function Minimiere(lngWert As Long, rngListe As Range) As Variant()
Dim intPos As Integer
Dim varArr() As Variant

lngOptWert = 10 ^ 9
varListe = rngListe.Value
intAnzT = UBound(varListe, 1)
ReDim intAkt(1 To intAnzT)
ReDim intOpt(1 To intAnzT)
ReDim varArr(1 To intAnzT)
Call Recursion(1, 1, lngWert)
For intPos = 1 To intAnzT
    varArr(intPos) = intOpt(intPos)
    'Minimiere = Minimiere & intOpt(intPos) & "; "
Next intPos
Minimiere = varArr

End Function
Sub Recursion(ByVal intEbene As Integer, ByVal intAktTower As Integer, ByVal lngRest As Long)
Dim intPos As Integer
Dim intTower As Integer
Dim intAktAnz As Integer
Dim intAktMax As Integer

For intTower = intAktTower To intAnzT
    intAktAnz = 0
    intAktMax = Application.RoundUp(lngRest / varListe(intTower, 2), 0)
    Do While intAktAnz <= intAktMax
        intAktAnz = intAktAnz + 1
        lngRest = lngRest - varListe(intTower, 2)
        intAkt(intTower) = intAktAnz
        lngAktWert = lngAktWert + varListe(intTower, 3)
        If lngRest <= 0 Then
            If lngAktWert < lngOptWert Then
                lngOptWert = lngAktWert
                For intPos = 1 To intAnzT
                    intOpt(intPos) = intAkt(intPos)
                Next intPos
            End If
            Exit Do
        Else
            If intEbene < intMaxE Then
                Call Recursion(intEbene + 1, intTower + 1, lngRest)
            End If
        End If
    Loop
    lngRest = lngRest + intAkt(intTower) * varListe(intTower, 2)
    lngAktWert = lngAktWert - intAkt(intTower) * varListe(intTower, 3)
    intAkt(intTower) = 0
Next intTower

End Sub
Hi
 
Hier die Formel für B4 noch mal etwas vereinfacht.
 
B4      =GANZZAHL(A4/B$2)+(REST(A4;B$2)<>0)*((REST(A4;B$2)>C$2)+(REST(A4;B$2)<2001)*-1)*(A4>2000)
 
Die Ergebnisse sind identisch mit der Funktion von Ego. Also hast du jetzt 2 funktionierende Varianten.
Ihr seid ja komplett wahnsinnig :D, vielen Dank euch beiden :100:
Hallo W..., Elex

zu:
Zitat:Die Ergebnisse sind identisch mit der Funktion von Ego. Also hast du jetzt 2 funktionierende Varianten.

Wenn die Aussage richtig wäre, gelte das aber nur für das aktuelle Zahlenbeispiel. Wenn sich die Kosten oder Leistungen der Tower ändern müste die Formel angepasst werden.
Aber auch mit diesem Zahlenbeispiel habe ich einen Unterschied (bei 26.000;27000; 51000;52000;...) und ein nicht gültiges Ergebnis in den Formel.

@ W...,

A) Ausgabe
wenn eine UDF für dich akzeptabel ist, könnte man die Ausgabe an dein ursprüngliches Format(Anzahl1;Name1;Anzahl2;Name2;Anzahl3;Name3) anpassen.
B) Anzahl der verschiedenen Tower
Zur Zeit werden nur die Kombinationen aus drei verschiedenen Tower berechnet (nach den Ausgabefeldern in deinem Beispiel). Mit deinen Beispieldaten ist eine Erweiterung auch nicht notwendig. Das kann man im Programm über die Konstante intMaxE anpassen. Auf Wunsch kann ich die Anzahl der verschiedenen Tower auch als Parameter im Funktionsaufruf einbauen.
@Ego Danke für deine Mühen, voraussichtlich wird sich die Leistung und die Kosten der einzelnen Tower in nächster Zeit nicht verändern, in ein paar Jahren kann sich dies natürlich ändern da gebe ich dir Recht und es wäre in dem Fall garnicht mal so dumm das ganze zu parametrisieren. Du musst aufpassen, oben Rechts in dem Darstellungsbeispiel ist eine Tabelle mit 5 unterschiedlichen Towern, es wurden lediglich 3 verschiedene Tower in dem Beispiel verwendet, dennoch müssen alle 5 berücksichtigt werden. Außerdem werden vermutlich noch 2 weitere Tower hinzugefügt, Tower F mit 50000 m³/h und 75000 m³/h, allerdings sind für diese beiden die Kosten noch nicht bekannt. Eine UDF stellt keine Probleme dar, wenn es möglich ist mit den genannten Fakten deine Funktion noch weiter anzupassen, wäre ich dir natürlich mehr als dankbar :)

edit: Vermutlich wird Tower F grob 80.000€ und Tower G grob 90.000€ kosten.

Gruß Weltenweit
Hallo Weltenweit,

in der Anlage die überarbeitete UDF ("Minimiere") und hier noch einige Bemerkungen:

A) Änderung
Die Ausgabe des Optimalen Ergebnisses erfolgt jetzt in der Form Anzahl1;Name1;Anzahl2;Name2;... (Spalten J:O) .
Die Anzahl verschiedener Tower in einer Kombination muss jetzt als Parameter mitgegeben werden.

B) Parameter
1. Parameter Ein Bezug auf den zu optimierende Wert. Die Zelle muss eine Zahl enthalten. Eine Rundung auf den nächsten Tausender ist nicht notwendig.
2. Parameter Ein Bezug auf den Bereich mit den Angaben zu den verschiedenen Tower.
Der Bereich muss mindestens 3 Spalten umfassen.
Spalte 1 = Bezeichnung
Spalte 2 = Leistung
Spalte 3 = Kosten
Die Anzahl der Tower wird durch die Anzahl der Zeilen des Bereichs bestimmt. Die Reihenfolge ist für die Berechnung beliebig (siehe aber Laufzeit).
In der Ausgabe werden die Tower in der Reihenfolge der Liste ausgegben.
3. Parameter Die Anzahl der verschiedenen Tower in einer zu untersuchenden Kombination als Wert (siehe auch Laufzeit).

C) Matrixfunktion
Da die Funktion mehrere Werte zurückliefert muss sie als Matrixfunktion eingerichtet werden.
Bei der Eingabe 2*3.Parameter Zellen nebeneinander markieren und die Eingabe (ohne geschweifte Klammern) mit Strg+Shift+Enter abschliessen. Es erscheinen in der Bearbeitungszeile geschweifte Klammern um die Formel.

D) Laufzeit
Das Programm untersucht alle möglichen Kombinationen und gibt die Kombination mit den kleinsten Kosten aus.
1. Anzahl
Die Laufzeit steigt exponentiell mit der Anzahl der unterschiedlichen Tower und mit dem Wert des 3.Parameters.
Zwei zusätzlich Tower werden die Funktion zwar verlangsamen aber sind bestimmt noch gut machbar.
Mit den aktuellen Towerdaten werden die Optima immer nur aus 3 verschiedenen Tower zusammengestellt, selbst wenn ich über den 3. Parameter 5 verschiedene Tower zulasse.
Mit den beiden zusätzlichen Tower erwarte ich, dass nicht mehr als 4 verschiedene Tower genutzt werden.
2. Reihenfolge
Bei der Zusammenstellung der Kombinationen nutzt das Programm die Reihenfolge der Towerliste und bricht die Zusammenstellung einer Kombination ab, wenn die Kosten des bisher besten Ergebnisses überschritten ist. Daher sollte die Liste nach der Reihenfolge des besten Leistung/Preis-Verhältnis sortiert sein um die Laufzeit zu reduzieren.
Hallo Weltenweit,

sorry, hab die Bremse im Programm jetzt gelöst. Es sollte jetzt mehr als zehnmal so schnell sein.
Hallo,

Die VBA Lösung von Ego finde ich gut. Die Formellösung ist leider nicht belastbar, fürchte ich.

Anbei eine kleine Variation von Ego's Lösung. Ich habe Integer durch Long ersetzt und die Klasse SystemState eingefügt (gefühlt wurde aber nichts beschleunigt).

Viele Grüße,
Bernd P
Seiten: 1 2