Ich habe ein Netzwerk von Stationen in einem U-Bahn-System. Die Anzahl der Stationen, die Anzahl der Fahrkarten, die ich zwischen Stationen fahren kann und welche Stationen miteinander verbunden sind, werden in einer Textdatei als Eingabe für das Programm angegeben. Welche Stationen miteinander verbunden sind, werden in einer booleschen 2D-Matrix gehalten. Ich muss die Anzahl der Pfade von Station 0 und zurück zu 0 finden, die alle Tickets verwendet.Dynamische Programmierung - Zählen von Pfaden in einem U-Bahn-System
Dies ist eines der Beispiele:
In diesem Beispiel gibt es 7 Stationen und 5 Tickets. mit 0 starten und Rückkehr gibt es 6 Pfade:
0-1-2-3-4-0
0-1-5-3-4-0
0-1-6-3-4-0
0-4-3-6-1-0
0-4-3-5-1-0
0-4-3-2-1-0
I derzeit eine rekursive Lösung dafür, die in O läuft (n^k) (N die Anzahl der Stationen darstellt, während k die Nummer ist von Tickets), aber ich muss es in eine iterative, dynamische Programmierlösung in O (k * N^2) umwandeln, die an jeder Eingabe funktioniert.
#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
// We will represent our subway as a graph using
// an adjacency matrix to indicate which stations are
// adjacent to which other stations.
struct Subway {
bool** connected;
int nStations;
Subway (int N);
private:
// No copying allowed
Subway (const Subway&) {}
void operator= (const Subway&) {}
};
Subway::Subway(int N)
{
nStations = N;
connected = new bool*[N];
for (int i = 0; i < N; ++i)
{
connected[i] = new bool[N];
fill_n (connected[i], N, false);
}
}
unsigned long long int callCounter = 0;
void report (int dest, int k)
{
++callCounter;
// Uncomment the following statement if you want to get a feel
// for how many times the same subproblems get revisited
// during the recursive solution.
cerr << callCounter << ": (" << dest << "," << k << ")" << endl;
}
/**
* Count the number of ways we can go from station 0 to station destination
* traversing exactly nSteps edges.
*/
unsigned long long int tripCounter (const Subway& subway, int destination, int nSteps)
{
report (destination, nSteps);
if (nSteps == 1)
{
// Base case: We can do this in 1 step if destination is
// directly connected to 0.
if (subway.connected[0][destination]){
return 1;
}
else{
return 0;
}
}
else
{
// General case: We can get to destinaiton in nSteps steps if
// we can get to station S in (nSteps-1) steps and if S connects
// to destination.
unsigned long long int totalTrips = 0;
for (int S = 0; S < subway.nStations; ++S)
{
if (subway.connected[S][destination])
{
// Recursive call
totalTrips += tripCounter (subway, S, nSteps-1);
}
}
return totalTrips;
}
}
// Read the subway description and
// print the number of possible trips.
void solve (istream& input)
{
int N, k;
input >> N >> k;
Subway subway(N);
int station1, station2;
while (input >> station1)
{
input >> station2;
subway.connected[station1][station2] = true;
subway.connected[station2][station1] = true;
}
cout << tripCounter(subway, 0, k) << endl;
// For illustrative/debugging purposes
cerr << "Recursive calls: " << callCounter << endl;
}
int main (int argc, char** argv)
{
if (argc > 1)
{
ifstream in (argv[1]);
solve (in);
}
else
{
solve (cin);
}
return 0;
}
Ich bin nicht auf der Suche nach einer Lösung. Ich habe derzeit keine Ideen mehr und hoffe, dass mich jemand in die richtige Richtung lenken kann. Da ich dazu einen Bottom-up-Ansatz implementieren muss, wie würde ich anfangen, eine dynamische Programmiertabelle mit den kleinsten Teilproblemen zu entwickeln?
Müssen Sie DP verwenden? Und Sie finden alle solche Wege? –