Knapsack-Problem (Rucksack-Problem)
-
mein lösungsansatz funktioniert schon hab nur ein prob
int N=5; item items[5]; int maxKnown[100]; String itemKnown[100]; int sack (int cap) {int i, space, max, maxi=0, t; if (maxKnown[cap] != -1) return maxKnown[cap]; for (i = 0, max = 0; i < N; i++) if ((space = cap - items[i].size) >= 0) if ((t = sack(space) + items[i].val) > max) {max = t; maxi=i;} maxKnown[cap] = max; itemKnown[cap] = itemKnown[cap] + items[maxi].name; //items[i].count=items[i].count+1; return max;N anzahl wie viele Sachen es gibt die in den rucksack können also es gibt 5 unterschiedliche
cap größe des sacks
items ist meine klasse mit den sachen die es gibt
maxKnown[] speicher für den besten ermittelten wert
itemKnown[] in das array soll reingespeichert werden welche items im sack sindmeine item klasse
class item {public: String name; int size; int val; };meine objekte
items[0].name="Würstchen"; items[0].size=3; items[0].val=4; items[1].name="Wodka"; items[1].size=4; items[1].val=5; items[2].name="Fanta"; items[2].size=7; items[2].val=10; items[3].name="Pringles"; items[3].size=8; items[3].val=11; items[4].name="Pinjata"; items[4].size=9; items[4].val=13;jetzt will ich wie oben gesagt in itemKnown immer die items speichern, die für die bestelösung, im sack sind
ich möchte für einen sack der 12 größ die besten lösung haben das sieht man auch so 1 pinjata und 1 würstchen das gibt dan einen wert von 17. das bekomme ich auch heraus. blos wenn ich mir as array angucke kommt dann folgendes raus:
würstchen
würstchen
würstchen
würstchen
wodka
wodka
würstchenpringles
pinjatawürstchen
so die letzten 2 wären die richtige lösung sind aber die abstände dazwichen und gleih an pinjata pringles dran. kann mir da einer helfen das mit variabler größe das ich immer die richtigen items angezeigt bekomme und nicht immer alles bei denen er durchgegangen ist?
-
Die Ausgabe ist nach dem Value im Sack geordnet. D.h. in der 17. Zeile sollte das Würstchen erscheinen und in der 12. die Pinjata. Es wird für jeden max. Sack-Wert (val) nur das erste (!) item gespeichert.
Wenn Du als Ergebnis alle die Dinge haben möchtest, die in den Sack mit dem maximalen Wert passen, so musst Du den Inhalt im Return-Code mit zurückgeben, statt es global abzulegen. Das kann man z.B. in einer Liste von item's machen. Hier eine Alternative:#include <list> #include <numeric> // accumulate #include <string> // string struct AddVal { int operator()( int sum, const item& it ) { return sum + it.val; } }; std::list< item > sack2( int cap ) { int max_val = 0; std::list< item > maxi; for( item* i = items; i != items + sizeof(items)/sizeof(*items); ++i ) { int space = cap - i->size; if( space >= 0 ) // item '*i' passt in den Sack { std::list< item > t = sack2( space ); // liefert die item's mit max. Sack-Wert mit Sack-Größe 'space' const int t_val = std::accumulate( t.begin(), t.end(), i->val, AddVal() ); if( t_val > max_val ) // Sack hat größeres 'val' als max { max_val = t_val; t.push_front( *i ); // 1.Item noch hinzufügen maxi = t; } } } return maxi; }Die Liste, die von sack2( 12 ) erzeugt wird, enthält dann nur das Würstchen und die Pinjata.
Gruß
Werner
-
erst mal danke hab aber wegen folgendem prob keine ahnung
Kann man dawas machen kann den wert nicht in nem edit feld ausgeben
[C++ Error] Unit1.cpp(91): E2034 Cannot convert 'std::list<item,std::allocator<item> >' to 'AnsiString'
-
Der Richter schrieb:
Kann man dawas machen kann den wert nicht in nem edit feld ausgeben
[C++ Error] Unit1.cpp(91): E2034 Cannot convert 'std::list<item,std::allocator<item> >' to 'AnsiString'Das passt besser ins VCL-Forum.
-
Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum VCL/CLX (Borland C++ Builder) verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Hallo,
Häng einfach c_str() an dein Listenelement an, dann klappts auch mit dem AnsiString.
-
Braunstein schrieb:
Hallo,
Häng einfach c_str() an dein Listenelement an, dann klappts auch mit dem AnsiString.
sorry versteh ich nicht
-
Hallo
string Test = "A"; Edit->Text = Test.c_str();bis bald
akari
-
akari schrieb:
Hallo
string Test = "A"; Edit->Text = Test.c_str();bis bald
akariok soviel versteh ich jetzt. hab jetzt mehre variationen ausprobiert aber brings nicht hin. wie lautet der code genau anhand des beispiels oben?
-
Das ist hier doch etwas anderes. Du hast die Strings ja schon im richtigen Format, willst also nur darauf zugreifen;
Was willst du übrigens wohin speichern. In den obigen Quelltexten kommt kein Editfeld vor.
Hast du jetzt eine list<Item>?
Hier mal der Code zum Schreiben des ersten Eintrages in der list in ein Editfeld.std::list< item > Items; // jetzt die list anhand des Algorithmusses füllen std::list< item >::iterator it = Items.begin(); Edit->Text = it->name;oder mal zum Schreiben aller itemnamen in eine StringList
TStringList *list = new TStringList; // Schleife durchläuft die Liste und fügt alle Einträge einer StringList zu for(std::list< item >::iterator it = Items.begin(); it!=Items.end(); ++it) liste->Add(it->name); // irgendwas mit der StringList machen delete list; //löschen nicht vergessen
-
ja de funktion sack2 hat ja am ende nen return maxi das würde ich gerne in nem edit feld ausgeben