Autor Beitrag
klezmor
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: Sa 08.12.07 03:29 
Folgende Aufgabe: Man hat eine Menge von 6 Münzen, diese haben alle irgendwelche unterschiedlichen Werte, wobei eine Münze den Wert 1Cent hat. Nun soll man einen Algorithmus entwickeln, der die minimale Anzahl an Münzen herausfindet, welche man benötigt um einen bestimmten Wert darzustellen.
Bsp. der Wert lautet 34Cents und die Münzen: 1, 11, 12, 13, 15, 20 die minimale Anzahl wäre in diesem Fall 3 da 1*1+1*13+1*20=34( gibt vielleicht noch weiter möglichkeiten mit 3). Ich habe keine Ahnung wie man so etwas implementieren könnte. Möglicherweise rekursiv, aber ich komme nicht ganz drauf. Hat jemand eine ahnung? Es kommt hierbei nicht auf optimierung an sondern man kann alle möglichkeiten durchgehen.
Das Problem steckt also hauptsächlich in der Implementierung.

MFG Klezmor.

_________________
"Beware of bugs in the above code; I have only proved it correct, not tried it." Donald Knuth
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Sa 08.12.07 10:33 
Wenn die Münzwerte beliebig sein können, bleibt dir afaik nichts anderes übrig, als alle Möglichkeiten durchzuprobieren (was immer das hier auch genau heißen mag). Mit unserem Münzsystem (1,2,5,10,20,50) kann man geschickter vorgehen, indem man immer die größte passende Münze nimmt und dann weiter macht. Bei deinen Angaben versagt das Verfahren z.B. für den Wert 30.

_________________
We are, we were and will not be.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Sa 08.12.07 14:28 
Alles durchprobieren geht wohl etwa so: Du fängst bei Münze 1 an und probierst alle möglichen Anzahlen durch. Zuerst 0 Stück, dann 1 Stück, 2 Stück, usw. bis der Totalwert überschritten ist. Und für jede Anzahl für Münze 1 (0,1,2,...) probierst du alle Anzahlen für Münze 2 durch. Das geht einfach mit einer Rekursion. Der Aufwand einer solchen Berechnung ist exponential.
Dabei sollte bei deinem Beispiel sowas rauskommen:
ausblenden Münzanzahlen in blau, Werte schwarz, Bestlösungen orange
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
 0x1,2x11,1x12,0x13,0x15,0x20  Total: 3
 1x1,0x11,0x12,1x13,0x15,1x20  Total: 3
 1x1,3x11,0x12,0x13,0x15,0x20  Total: 4
 2x1,0x11,1x12,0x13,0x15,1x20  Total: 4
 3x1,1x11,0x12,0x13,0x15,1x20  Total: 5
 4x1,0x11,0x12,0x13,2x15,0x20  Total: 6
 6x1,0x11,0x12,1x13,1x15,0x20  Total: 8
 7x1,0x11,1x12,0x13,1x15,0x20  Total: 9
 8x1,0x11,0x12,2x13,0x15,0x20  Total: 10
 8x1,1x11,0x12,0x13,1x15,0x20  Total: 10
 9x1,0x11,1x12,1x13,0x15,0x20  Total: 11
10x1,0x11,2x12,0x13,0x15,0x20  Total: 12
10x1,1x11,0x12,1x13,0x15,0x20  Total: 12
11x1,1x11,1x12,0x13,0x15,0x20  Total: 13
12x1,2x11,0x12,0x13,0x15,0x20  Total: 14
14x1,0x11,0x12,0x13,0x15,1x20  Total: 15
19x1,0x11,0x12,0x13,1x15,0x20  Total: 20
21x1,0x11,0x12,1x13,0x15,0x20  Total: 22
22x1,0x11,1x12,0x13,0x15,0x20  Total: 23
23x1,1x11,0x12,0x13,0x15,0x20  Total: 24
34x1,0x11,0x12,0x13,0x15,0x20  Total: 34
klezmor Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: Sa 08.12.07 14:50 
Also nehmen wir mal an ich hab die Münzen: 1, 3, 5, 7, 11 Der Baum sähe dann für alle möglichkeiten folgendermaßen aus:
1.Schicht: 1-----------3---------5---------7-------------11
2.Schicht (1)--------(1,3)---(1,3,5)--(1,3,5,7)--(1,3,5,7,11)
3.Schicht (1)--------(1)(1,3) .... .... ....
4.Schicht (1) .....
usw.bis der Betrag 0 ist

Aber wie durchlafue ich einen solchen Baum , ich weiß einfach nciht, wie ich das rekursiv implementieren kann.
Ich muss letztendlich auch noch feststellen können wie viele Schichten ich durchlaufen bin um den betrag vollständig auf 0 gesetzt zu haben.
Bitte helft mir.



Gruß Klezmor

_________________
"Beware of bugs in the above code; I have only proved it correct, not tried it." Donald Knuth
F4n4T!C
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Sa 08.12.07 15:42 
rekursion ist ein böses thema...mein thema muss ich auch rekursiv lösen, aber im endeffekt ist eine rekursion, z.b. eine prozedur die sich immer wieder selber aufruft, bist zu einem "ende"

um es mal ganz einfach zu sagen

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
procedure muenze(a,b,c,d,e,f:integer)//hier sind die variablen die zurückgegeben werden
begin
  dann kommt hier dein ganzer quellcode;
  muenze(a,b,c,d,e,f);//damit ruft sich die prozedur selbst auf...et voila du hast eine rekursion
end;


um das problem zu lösen, müsste ich mich jetzt paar tage damit beschäftigen...bis wann brauchst du das programm?
blaueled
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 133

Win XP
D5
BeitragVerfasst: Sa 08.12.07 18:19 
Hallo,

du müsstest dein Münzen der Größe nach sortieren, und dann von oben nach unten probieren:

dein bsp:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
34 cent
münzen: 20,15,13,12,11,1

1. Vergleich
(34 - 20 (14)) > 0 --> 1. Münze ist 20, rest ist 14

2. Vergleich
(14 - 20 (-6)) > 0 --> nächste Münze
(14 - 15 (-1)) > 0 --> nächste Münze
(14 - 13 (1))  > 0 --> 2. Münze ist 13, rest ist 1

3. Vergleich
...
(1 - 1 (0))    = 0 --> 3. Münze ist 1, rest ist 0 --> Beenden


Das sollte die schnellste und am einfachsten Umzusetzende Methode sein

Blauled
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Sa 08.12.07 18:27 
@blaueled: Und genau dieses "Greedy"-Verfahren funktioniert nicht immer. Nimm 30 Cent:

20 Cent - 10 Cent bleiben übrig.

15, 13, 12, 11 Cent passen nicht, also werden 10 1-Cent-Münzen genommen. Die gesuchte Lösung wäre aber 2x15 Cent gewesen. Man muss schon komplizierter ran - delfiphan hat da glaube ich das richtige Verfahren - das muss man nur in Code umsetzen ;-)

_________________
We are, we were and will not be.
klezmor Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: Sa 08.12.07 18:40 
Ja genau der greedy Algo, ist nur optimal für unsere Währungssysteme.
Aber so wie ich Delphifan verstanden habe, probiert er 6^x(x=rekursionstiefe) möglichkeiten durch, ich möchte die komplexität ein wenig senken in dem ich unterscheide zwischen: nimm erst eine 2er münze und dann eine 10 ner, wie in meinem baum beschrieben. Wobei sich natürlich für große x die Komplexitäten nicht groß unterscheiden, bzw. in landau notation gleich sind(da beide exponentiell).

_________________
"Beware of bugs in the above code; I have only proved it correct, not tried it." Donald Knuth
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Sa 08.12.07 18:49 
Ob ein effizientes Lösungsverfahren existiert (für den allgemeinen Fall), welche garantiert die richtigen Lösungen findet, ist fragwürdig. Wenn nämlich alle Münzen Primzahlen sind, entspricht die Aufgabe einer Primfaktorenzerlegung. Wenn du hier einen effizienten Algorithmus findest, bist du Millionär ;). (Edit: Die Fragestellung bei der Primfaktorenzerlegung ist anders, da kennt man normalerweise die Faktoren nicht schon am Anfang und die Zerlegung ist eindeutig)

user profile iconklezmor hat folgendes geschrieben:
nimm erst eine 2er münze und dann eine 10 ner
Wenn du alle Möglichkeiten durchprobierst, ist die Reihenfolge der Münzen egal.

user profile iconklezmor hat folgendes geschrieben:
Aber so wie ich Delphifan verstanden habe, probiert er 6^x(x=rekursionstiefe) möglichkeiten durch
Nein, die Rekursionstiefe ist 6 und es werden 829 Möglichkeiten durchprobiert, nämlich alle Möglichkeiten mit der Summe kleinergleich dem Totalwert.
Wenn es eine Münze gibt, die eindeutig mit minimaler Anzahl durch andere Münzen zusammengesetzt werden kann, kann man die wegoptimieren (das ist bei allen Währungen hoffentlich bei allen Münzen der Fall ;) )

user profile iconGausi hat folgendes geschrieben:
Man muss schon komplizierter ran - delfiphan hat da glaube ich das richtige Verfahren - das muss man nur in Code umsetzen ;-)
Die Rekursionsfunktion ist relativ kurz, 10 Zeilen ;)


Zuletzt bearbeitet von delfiphan am So 09.12.07 00:51, insgesamt 1-mal bearbeitet
>M@steR<
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 288
Erhaltene Danke: 3



BeitragVerfasst: Sa 08.12.07 22:59 
Gelöscht


Zuletzt bearbeitet von >M@steR< am Di 17.09.13 01:59, insgesamt 1-mal bearbeitet
>M@steR<
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 288
Erhaltene Danke: 3



BeitragVerfasst: Sa 08.12.07 23:36 
Gelöscht


Zuletzt bearbeitet von >M@steR< am Di 17.09.13 01:59, insgesamt 1-mal bearbeitet
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 09.12.07 00:21 
user profile icon>M@steR< hat folgendes geschrieben:
ich habe den algo jetzt als quellcode und er funzt perfekt!

Und was ist mit 23x1 + 1x11? Gibt auch 34 ;) Es gibt übrigens zwei minimale Lösungen, dein Algorithmus findet nur die eine.

Übrigens weiss ich nicht, ob es sinnvoll ist, wenn du deinen Quelltext hier reinpostest...


Zuletzt bearbeitet von delfiphan am So 09.12.07 00:25, insgesamt 1-mal bearbeitet
>M@steR<
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 288
Erhaltene Danke: 3



BeitragVerfasst: So 09.12.07 00:24 
Gelöscht


Zuletzt bearbeitet von >M@steR< am Di 17.09.13 01:59, insgesamt 2-mal bearbeitet
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 09.12.07 00:31 
Du hast keine Garantie, dass du die beste Lösung findest.
>M@steR<
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 288
Erhaltene Danke: 3



BeitragVerfasst: So 09.12.07 00:32 
Gelöscht


Zuletzt bearbeitet von >M@steR< am Di 17.09.13 01:59, insgesamt 1-mal bearbeitet
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 09.12.07 00:32 
Erst bestes Beispiel schlägt schon fehl: 1*13 + 3*15 + 1*20 = 78 (5 Münzen)
Deine Minimallösung: 6*13 = 78 (6 Münzen)
>M@steR<
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 288
Erhaltene Danke: 3



BeitragVerfasst: So 09.12.07 00:37 
Gelöscht


Zuletzt bearbeitet von >M@steR< am Di 17.09.13 01:59, insgesamt 1-mal bearbeitet
klezmor Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: So 09.12.07 15:26 
user profile icondelfiphan hat folgendes geschrieben:
Erst bestes Beispiel schlägt schon fehl: 1*13 + 3*15 + 1*20 = 78 (5 Münzen)
Deine Minimallösung: 6*13 = 78 (6 Münzen)


Delphifan hat Recht, die Lösung bringt wirklich nicht immer die minimale Anzhahl der Münzen heraus. Aber um was es mir eigentlich ging, ist dass, der baum welchen ich oben hingezeichnet habe weniger kombinationen enthält wie die lösung von delphifan und somit, wenn auch nciht viel, aber dennoch ein wenig schneller zu berechnen wäre.

Oder täusche ich mich da, ganz sicher bin ich mir auch net?

_________________
"Beware of bugs in the above code; I have only proved it correct, not tried it." Donald Knuth
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 09.12.07 16:22 
Ist wieder mal ein typisches Rucksack-Problem:

Sieht in PHAssemPler (hingeschmiert) so aus:

ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
<?php

$coins = array(1,11,12,13,15,20);

$value = 78;

$minsolution = array();

$stack = array(array());

while(count($stack)) {
    $tmp = array_shift($stack);

    $tmpsum = array_sum($tmp);

    if ($tmpsum == $value) {
        $minsolution = $tmp;
        break;
    }

    if ($tmpsum > $value) {
        continue;
    }

    foreach($coins as $newcoin) {
        $newtmp = $tmp;
        $newtmp[] = $newcoin;
        $stack[] = $newtmp;
    }
}

var_dump($minsolution);
echo array_sum($minsolution);

?>


Ist ne typische Breitensuche ... Geht aber noch stark zu optimieren ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 09.12.07 18:08 
@typisches Rucksackproblem: Beim Rucksackproblem ist die Anzahl Gegenstände egal. Es geht dort nicht um die Minimierung der Anzahl sondern Maximierung des Nutzens. Ausserdem soll dort das Gewicht kleinergleich einem Maximalwert sein, hier muss der Totalbetrag genau stimmen. Und man kann einen Gegenstand genau null oder einmal in den Rucksack einpacken, ich darf/muss aber mehrere Stücke einer Münzart nehmen.