Witam,
Na podstawie informacji zawartych w Wprowadzenie do algorytmów Cormena i materiałów z sieci napisałem algorytm Edmondsa-Karpa do wyznaczania największego możliwego przepływu w sieci (macierz sąsiedztwa, przeszukiwanie wszerz). Niestety nie działa. Debbuger w VS2012 pokazuje, ze program nie wychodzi z pętli:

 

while (i != source)
{
    v1 = father[i];
    flow[v1][i] = flow[v1][i] + flow_path[outlet];
    flow[i][v1] = flow[i][v1] - flow_path[outlet];
    i = v1;
}

Jak rozumiem wynika to z tego, że w pewnym momencie dochodzi do sytuacji, w której wierzchołek 'a' jest poprzednikiem 'b' i odwrotnie. Od dłuższego czasu nie mogę poradzić sobie z tym problemem, proszę o pomoc.

ps. Ujście jest "na sztywno" ustawione na 6 ponieważ testuje algorytm na grafie, którego ujściem jest właśnie wierzchołek 6.
ps2. MAX_INT to maksymalna wartość int z biblioteki <limits>.

Cały kod algorytmu:

void FordFulkerson::doFordFulkerson(bool print_console)
{
	// Plik do zapisu
	ofstream file;

	// Zmienna do mierzenia czasu
	Timer timer;

	// Zrodlo
	int source = graph->getStartVertex();

	// Ujscie
	int outlet = 6;

	// Maksymalny przeplyw poczatkowo ustawiony na zero
	int flow_max = 0;

	// Macierz przeplywow w krawedzich
	int **flow = new int*[graph->getVerticesCount()];

	for (int i = 0; i < graph->getVerticesCount(); i++)
	{
		flow[i] = new int[graph->getVerticesCount()];
	}

	// Ustawiam wartosci przeplywow w macierzy przeplywow na zero
	for (int i = 0; i < graph->getVerticesCount(); i++)
	{
		for (int j = 0; j < graph->getVerticesCount(); j++)
		{
			flow[i][j] = 0;
		}
	}

	// Tablica, w ktora wpisuje poprzednika - 'ojca' danego wierzcholka
	int *father = new int[graph->getVerticesCount()];

	// Tablica, w ktorej przechowuje przepustowosc sciezek
	int *flow_path = new int[graph->getVerticesCount()];

	// Kolejka
	list <int> queue;

	// Pomocnicze
	int escape = 0; // do wychodzenia z zagniezdzonych petli
 	int v1 = 0;     // wierzcholek 1
	int current_flow = 0; // przechowuje tymczasowy, aktualny przeplyw

   /*********************************************************
	** Wlasciwy algorytm Forda-Fulkersona (Edmondsa-Karpa) **
	*********************************************************/

	// Rozpoczęcie pomiaru czasu wykonywania
	timer.startTimer();

	do
	{
		// Zeruje tablice poprzednikow
		for (int i = 0; i < graph->getVerticesCount(); i++)
		{
			father[i] = 0;
		}

		// Ustawiam poprzednik zrodla na -1, poniewaz zrodlo nie ma poprzednika
		father[source] = -1;

		// Przeplyw przez zrodlo ustawiam na nieskonczony
		flow_path[source] = MAX_INT;

		// Zeruje kolejke
		queue.clear();

		// Dodaje zrodlo do kolejki
		queue.push_back(source);

		// Zeruje escape
		escape = 0;

		while (queue.size())
		{
			// Wpisuje do v1 pierwszy element z kolejki,
			// a nastepnie go usuwam
			v1 = queue.front();
			queue.pop_front();

			// Sprawdzam sasiadow wierzcholka v1,
			// przegladam matrix[v1][]
			for (int i = 0; i < graph->getVerticesCount(); i++)
			{
				// Wyznaczam przepustowosc residualna dla krawedzi v1->i,
				// jesli takiej krawedzi nie ma w liscie sasiedztwa,
				// otrzymam zero (brak krawedzi w matrix oznaczony jest przez zero)
				current_flow = graph->matrix[v1][i] - flow[v1][i];

				// Sprawdzam czy krawedz istnieje i czy byla juz wybrana,
				// przez metode Forda - Fulkersona
				if (current_flow && !father[i])
				{
					father[i] = v1;

					// Dla wierzcholka 'i' obliczam  przepustowosc residualna - jest to mniejsza wartosc z przepustowosci
					// sciezki dla poprzednika 'v1' i biezacej przepustowosci residualnej krawedzi v1->i
					if (flow_path[v1] > current_flow)
					{
						flow_path[i] = current_flow;
					}

					else
					{
						flow_path[i] = flow_path[v1];
					}

					// Jesli osiagnalem ujscie
					if (i == outlet)
					{
						// Zwiekszam maksymalny przeplyw sieci 
						// o przepustowosc residualna sciezki
						flow_max = flow_max + flow_path[outlet];

						// Cofam sie wstecz po sciezce, zwiekszam przeplywy wzdluz jej kierunku
						// i zmniejszam w kierunku przeciwnym
						while (i != source)
						{
							v1 = father[i];
							flow[v1][i] = flow[v1][i] + flow_path[outlet];
							flow[i][v1] = flow[i][v1] - flow_path[outlet];
							i = v1;
						}

						// Ustawienie escape sluzy do wyjscia z zagniezdzonych petli
						escape = 1;
						break; 
					}

					// Jesli 'i' nie jest ujsciem 'outlet' to dadaje do kolejki
					queue.push_back(i);
				}
			}

			// Wyjscie z petli while(queue.size()), jesli znaleziono sciezke
			if (escape)
			{
				break;
			}
		}

		// Wyjscie z petli do..while(true), jesli nie znaleziono sciezki
		if (!escape)
		{
			break;
		}
		
	} while(true);

	// Zakonczenie pomiaru
	timer.stopTimer();

	// Zapisanie czasu wykonania do zmiennej skladowej klasy
	this->setFordFulkersonTime(timer);

	// Wyswietlenie wyniku na konsoli, jesli wlaczone
	if (print_console)
	{
		cout << endl << "Wyznaczony przeplyw sieci:" << endl;
		cout << "Zrodlo: " << graph->getStartVertex() 
			<< "    Ujscie: " << outlet << "    Przeplyw max: " << flow_max << endl << endl;

		

		cout << endl << endl;
		cout << "Czas wykonania: " << setprecision(15) << getFordFulkersonTime().getDuration() << " ms" << endl << endl << endl;
	}

	// Zapisanie wyniku do pliku
	file.open("Results/fordfulkerson.txt", ios::app);

	for(int i = 0; i < graph->getVerticesCount(); i++)
	{
		for(int j = 0; j < graph->getVerticesCount(); j++)
			{
				if(graph->matrix[i][j])
				{
					cout << i << " -> " << j << " "
					<< flow[i][j] << "/" << graph->matrix[i][j] << endl;
				}
			}
	
	}

	// Czyszczenie pamieci
	delete [] flow_path;
	delete [] father;

	for (int i = 0; i < graph->getVerticesCount(); i++)
	{
		delete [] flow[i];
	}

    delete [] flow;
}