Ich arbeite derzeit an einer Hausaufgabe, um den Bellman-Ford-Algorithmus zu implementieren. Bis jetzt habe ich es geschafft, das bereitgestellte Diagramm zu lesen, es in einen Vektor zu platzieren (einen 1d-Vektor zu verwenden, um eine 2d-Eins mit Reihen-Großordnung darzustellen), um sie als Matrix zu verwenden. Ich benutze eine Struktur, die das Gewicht der Kante verfolgt, eine boolesche für ob es unendlich ist (keine Kante existiert) und eine Variable, um den vorhergehenden Knoten zu verfolgen.Implementieren Bellman-Ford-Algorithmus C++
Was mich ratlos ist, implementiert tatsächlich den Dang-Algorithmus. Ich habe den Pseudocode von http://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm gelesen, aber ich habe eine schwierige Zeit zu begreifen, wie man den Algorithmus verwendet. Die ersten 80 Zeilen lesen die Datei ein, initialisieren den Vektor und werfen die Werte an der richtigen Stelle in den Vektor. Darunter habe ich angefangen, den Algorithmus zu implementieren. Ich habe ein paar spezifische Fragen.
1) In allen Erklärungen des Algorithmus, den ich gefunden habe, arbeiten Sie den Algorithmus Anzahl der Knoten - 1 mal. In einigen Implementierungen, die ich gesehen habe, tendiere ich dazu, bei 1 zu beginnen. Warum ist das? Und macht das mit meiner Implementierung noch Sinn?
2) Weiter im Wikipedia Pseudocode, es wird gesagt, um jede Kante u, v zu überprüfen, wobei u der Startknoten und v der Endknoten ist. In meiner Matrix müsste ich, soweit ich das verstehen kann, das Gewicht/den Wert jeder Zeile, jedes Spaltenpaars überprüfen und sehen, ob es einen besseren Pfad gibt. Ich bin ... nicht sicher, ob ich das richtig erkläre oder es sogar als diesen Punkt verstehe. Jede Beratung/Anleitung/Hinweise/Demonstrationen würde sehr geschätzt werden. Der Quellcode gefolgt von einer Paste der Demo-Eingabe des Instruktors ist unten.
#include <fstream>
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
struct graphNode
{
int value; //Weight of the edge
bool isInfinity; //Boolean to flag an edge as infinity
int pred; //predecessor node
};
// Code for reading inputfile cribbed and modified from http://stackoverflow.com/questions/7651243/c-read-a-file-name-from-the-command-line-and-utilize-it-in-my-file
int main(int argc, char** argv)
{
ifstream input; // ifstream for the input
string inFile = ""; //name of the input file
int row; //Variable to keep track of what row we're inputting data for
int col; //Variable to keep track of a column thingie, expand on this later
int infinity = 99999999;
int nodeCount; //Number of nodes from input file
int edgeCount = 0; //Number of edges from the input file
vector<graphNode> edgeList; //2D list of edges, order is a->b
edgeList.push_back(graphNode());
edgeList[0].value = 0;
edgeList[0].isInfinity = false;
edgeList[0].pred = -1;
if(argc == 2)
{
inFile = argv[1];
}
else
{
cout << "Usage: ./a.out inputFile\n";
return 1;
}
input.open(inFile.c_str()); // opening the provided file
if(input.is_open()) // making sure the input is open
{
input >> nodeCount; //Grabbing the number of nodes from the first value of the file
for(int i = 1; i < nodeCount*nodeCount; i++)
{
edgeList.push_back(graphNode());
edgeList[i].value = infinity;
edgeList[i].isInfinity = true;
edgeList[i].pred = -1;
}
//Putting data from the file into the vector array
while(!input.eof())
{
input >> row; //For each cycle through the list, we grab the first number on the line to get which x value (start vertex) we're working with
while(input.peek() != '\n' && input.peek() != '\r' && !input.eof())
{
input >> col;
input >> edgeList[((row-1)*nodeCount)+(col-1)].value;
edgeList[((row-1)*nodeCount)+(col-1)].isInfinity = false;
edgeList[((row-1)*nodeCount)+(col-1)].pred = row;
edgeCount++;
}
}
input.close(); //Closing our input file since we don't need it anymore
}
else
{
cout << "Error, something happened with the input." << endl;
return 1;
}
//for(int i = 0; i < nodeCount - 1; i++)
//{
//for(int r = 0; r < nodeCount - 1; r++)
//{
//for(int c = 0; r < nodeCount - 1; c++)
//{
//if(r == c) continue;
//if(edgeList[r][c].isInfinity) continue;
//if(edgeList[i][r] + edgeList[r][c] < edgeList[c][i])
}
Demo-Eingang:
10
3 6 4 9 0 7 8
8 5 3 7 3 4 -2
5 10 2 8 1 4 1
2 6 -3 1 3 7 1
1 10 -1 2 2 4 -2
10 9 -3 1 3 7 2 5 1
7 3 0 10 1 2 1 8 2
9 6 6 3 4 10 7
4 8 5 1 9 5 6
6 2 4 3 0 9 0
Nur leicht verwandt: Ändere dies: 'while (! Input.eof())' zu diesem 'while (input >> row)' und entferne die Extraktion sofort innerhalb der Schleife. Sie könnten dies auch verfeinern, indem Sie 'std :: getline()' und einen intermediären 'istringstream' für diese Verarbeitungsschleife pro Zeile verwenden. – WhozCraig
Für was es wert ist, hier ist ein Link zu meiner Python-Implementierung, vielleicht wird es helfen: https://github.com/ezod/hypergraph/blob/master/hypergraph/path.py#L58 – ezod