Attualmente sto lavorando a un compito a casa per implementare l'algoritmo Bellman-Ford. Finora, sono riuscito a leggere nel grafico fornito, metterlo in un vettore (usando un vettore 1d per rappresentare un 2d uno con ordine di riga maggiore) da usare come matrice. Sto usando una struttura che tiene traccia del peso del bordo, un valore booleano per indicare se è infinito (nessun fronte esiste) e una variabile per tenere traccia del nodo precedente.Implementazione dell'algoritmo Bellman-Ford C++
Ciò di cui sono perplesso è in realtà l'implementazione dell'algoritmo dang. Ho letto lo pseudocodice da http://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm ma ho difficoltà a capire come utilizzare l'algoritmo. Le prime 80 righe stanno leggendo nel file, inizializzando il vettore, gettando i valori nel vettore nel posto giusto. Di seguito è quello che ho iniziato ad implementare per l'algoritmo. Ho alcune domande specifiche.
1) In tutte le spiegazioni dell'algoritmo che ho trovato, si lavora l'algoritmo # di nodi - 1 volta. In alcune delle implementazioni che ho visto, sono tendenzialmente iniziato a 1. Perché è questo? Inoltre, con la mia implementazione, ha ancora senso?
2) Più avanti nello pseudocodice di wikipedia, si dice di verificare ogni spigolo u, v, essendo il vertice di partenza u e il vertice di fine v. Nella mia matrice, per quanto posso capire, vorremmo dire che devo controllare il peso/valore di ogni riga, la coppia di colonne e vedere se c'è un percorso migliore. Non sono ... sicuro se lo sto spiegando correttamente o addirittura lo capisco come questo punto. Qualsiasi consiglio/guida/suggerimento/dimostrazione sarebbe molto apprezzato. Il codice sorgente seguito da una copia dell'ingresso dimostrativo dell'istruttore è riportato di seguito.
#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])
}
ingresso Demo:
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
Solo leggermente correlato: Cambia questo: 'while (! Input.eof())' a questo 'while (input >> row)' e rimuove l'estrazione immediatamente all'interno del ciclo. Si potrebbe anche affinare questo per essere significativamente più puliti usando 'std :: getline()' e un 'istringstream' intermedio per quel ciclo di gestione per riga. – WhozCraig
Per quello che vale, ecco un collegamento alla mia implementazione Python, forse aiuterà: https://github.com/ezod/hypergraph/blob/master/hypergraph/path.py#L58 – ezod