Hoi, ik probeer een recursieve implementatie van het Towers of Hanoi probleem te maken in c++. Alle algoritmen die ik gevonden heb op internet printen iets in zo'n trant van "move disk 1 from peg A to peg B".
Zo'n oplossing heb ik zelf ook al geprogrammeerd en dat is ook niet zo lastig, want je kunt gewoon de linkse, middelste en rechtse peg swappen door de volgorde van de parameters te veranderen. Nu wil ik iets anders proberen: ik wil na (of vóór) elke stap de state printen van een peg, d.w.z: de disks op volgorde van groot naar klein, bijvoorbeeld:
L: 5 4 3 2 1
M:
R:
...zou dan de begin state zijn.
Ik wil dit probleem oplossen door gebruik te maken van 3 vectoren die de pegs representeren. Het nadeel van de recursieve hanoi functie is alleen dat het swappen van de volgorde van de vectoren niet dezelfde werking heeft als het swappen van de pegs: de werking van het torens van Hanoi probleem zit al impliciet in de recursie en ik vind het daarom lastig om een vector representatie van het probleem te maken.
Ik zou namelijk het laatste positieve getal uit de vector (in dit geval 1) moeten vervangen door een 0, en de eerste 0 moeten vervangen door de 1, terwijl het consistent blijft met het hanoi algoritme. Ik wil me graag beperken tot recursie in dit topic.
[code=c++]
int solve_hanoi (int n, vector <int>& left_peg, vector <int>& right_peg, vector <int>& mid_peg)
{
if (n == 0)
return 0;
else
{
solve_hanoi (n - 1, left_peg, mid_peg, right_peg);
int a = left_peg.back();
left_peg.pop_back();
right_peg.push_back(a);
cout << endl << endl << "Left:";
for (int i = 0; i < left_peg.size(); i++)
cout << left_peg[i] << " ";
cout << endl << "Mid:";
for (int i = 0; i < mid_peg.size(); i++)
cout << mid_peg[i] << " ";
cout << endl << "Right:";
for (int i = 0; i < right_peg.size(); i++)
cout << right_peg[i] << " ";
solve_hanoi(n - 1, mid_peg, right_peg, left_peg);
}
}
void tower_of_hanoi (int n)
{
vector <int> left_peg;
vector <int> mid_peg;
vector <int> right_peg;
for (int i = n; i > 0; i--)
{
left_peg.push_back(i);
}
solve_hanoi(n, left_peg, right_peg, mid_peg);
}
[/code=c++]
Mijn huidige code resulteert in het printen van het woord "left" met elke keer een random integer erachter, dit zo'n 10000 keer, totdat de limiet van een integer is gebruikt en dan crasht het programma.
Voor de duidelijkheid: ik begrijp hoe het Hanoi probleem kan worden opgelost met recursie, dat is het probleem ook niet, het probleem ligt hem bij het feit dat je op vectoren operaties uit kan voeren zoals .push_back, maar ik niet weet hoe ik die dan als parameters kan meegeven in de recursieve aanroep.
Zo'n oplossing heb ik zelf ook al geprogrammeerd en dat is ook niet zo lastig, want je kunt gewoon de linkse, middelste en rechtse peg swappen door de volgorde van de parameters te veranderen. Nu wil ik iets anders proberen: ik wil na (of vóór) elke stap de state printen van een peg, d.w.z: de disks op volgorde van groot naar klein, bijvoorbeeld:
L: 5 4 3 2 1
M:
R:
...zou dan de begin state zijn.
Ik wil dit probleem oplossen door gebruik te maken van 3 vectoren die de pegs representeren. Het nadeel van de recursieve hanoi functie is alleen dat het swappen van de volgorde van de vectoren niet dezelfde werking heeft als het swappen van de pegs: de werking van het torens van Hanoi probleem zit al impliciet in de recursie en ik vind het daarom lastig om een vector representatie van het probleem te maken.
Ik zou namelijk het laatste positieve getal uit de vector (in dit geval 1) moeten vervangen door een 0, en de eerste 0 moeten vervangen door de 1, terwijl het consistent blijft met het hanoi algoritme. Ik wil me graag beperken tot recursie in dit topic.
[code=c++]
int solve_hanoi (int n, vector <int>& left_peg, vector <int>& right_peg, vector <int>& mid_peg)
{
if (n == 0)
return 0;
else
{
solve_hanoi (n - 1, left_peg, mid_peg, right_peg);
int a = left_peg.back();
left_peg.pop_back();
right_peg.push_back(a);
cout << endl << endl << "Left:";
for (int i = 0; i < left_peg.size(); i++)
cout << left_peg[i] << " ";
cout << endl << "Mid:";
for (int i = 0; i < mid_peg.size(); i++)
cout << mid_peg[i] << " ";
cout << endl << "Right:";
for (int i = 0; i < right_peg.size(); i++)
cout << right_peg[i] << " ";
solve_hanoi(n - 1, mid_peg, right_peg, left_peg);
}
}
void tower_of_hanoi (int n)
{
vector <int> left_peg;
vector <int> mid_peg;
vector <int> right_peg;
for (int i = n; i > 0; i--)
{
left_peg.push_back(i);
}
solve_hanoi(n, left_peg, right_peg, mid_peg);
}
[/code=c++]
Mijn huidige code resulteert in het printen van het woord "left" met elke keer een random integer erachter, dit zo'n 10000 keer, totdat de limiet van een integer is gebruikt en dan crasht het programma.
Voor de duidelijkheid: ik begrijp hoe het Hanoi probleem kan worden opgelost met recursie, dat is het probleem ook niet, het probleem ligt hem bij het feit dat je op vectoren operaties uit kan voeren zoals .push_back, maar ik niet weet hoe ik die dan als parameters kan meegeven in de recursieve aanroep.
[ Voor 9% gewijzigd door Neophyte808 op 17-01-2012 02:42 ]