Algorytm Dijkstry

0

Witam!
Szukam implementacji algorytmu Dijkstry w C. Ponieważ jestem początkująca więc najlepiej byłoby gdyby było to rozwiązanie jak najmniej skomplikowane:)

0

A niech tam...

//BADANIA OPERACYJNE - wyklad: 13.01.2001 r.
//SHORTEST PATH by DIJKSTRA
//rozwiazanie problemu najkrotszej sciezki metoda Dijkstra

#include <conio.h>
#include <iostream.h>

//definicja stalej - Dostatecznie Duza Liczba
const int DDL = 9999;
//realizujemy program na duzej tablicy, tablice alokowane dynamicznie
//bardzo by skomplikowaly czytelnosc programu
const int MAX = 30;
//poniewaz tablice w jezyku C sa indeksowane od zera, program operuje na
//pomniejszonych - i tak w procedurach miasto nr 1 jest traktowane jako
//miasto nr 0 - nie ma to jednak wplywu na wyniki dzialania programu.
void main(void)
{
char klawisz;				//sprawdzanie jaki klawisz zostal nacisniety
int ile_w;					//ilosc wierzcholkow
int siec[MAX][MAX];		//nasza siec zapisana jako tablica n*n
int T[MAX];					//do jakiego zbioru nalezy wierzcholek(0 - S, 1 - T)
int TJ[MAX];				//oszacowane odleglosci
int poprzednik[MAX];		//poprzedniki wierzcholkow
int sciezka[MAX];			//najkrotsza sciezka
int petla0, petla1;		//zmienne pomocnicze - petle
int start; 					//punkt startowy
int koniec;					//punkt koncowy
int ostatni;				//ostatni analizowany wierzcholek;
int s_ost;					//odleglosc od punktu startowego
int minimum;            //zmienna pomocnicza - szukamy minimalnej drogi
int pozycja;            //zmienna pomocnicza - j.w. ele interesuje nas miasto

//wprowadzanie ilosc wierzcholkow
clrscr();
cout << "Wprowadz ilosc wierzcholkow (<" << MAX <<"): ";
cin >> ile_w;

cout << "Wprowadz odleglosci pomiedzy wierzcholkami" << endl;
cout << "Jesli wierzcholkami nie maja polaczenia wpisz \"0\"" << endl << endl;
//wprowadzamy odleglosci miedzy wierzcholkami, automatycznie zapisujac DDL
//dla tego samego wierzcholka. Aby uproscic wpisywanie danych pozwalamy na
//wpisywanie zera, jesli wierzcholki nie maja polaczenia - program
//automatycznie zamienia je na DDL
for(petla0 = 0; petla0 < ile_w; petla0++)
	for(petla1 = 0; petla1 < ile_w; petla1++)
		{
		if(petla0 == petla1) siec[petla0][petla1] = DDL;
			else
			{
			cout << "Wprowadz odleglosc z miasta "
				<< (petla0 + 1) << " do miasta " << (petla1 + 1) << " : ";
			cin >> siec[petla0][petla1];
			if(siec[petla0][petla1] == 0)
				siec[petla0][petla1] = DDL;
			}
		}

do
	{
	clrscr();
	cout << "Wprowadz punkt startowy: "; cin >> start;
	cout << "Wprowadz punkt koncowy: "; cin >> koniec;

	//ustawianie wartosci poczatkowych
	//ustawiamy ostatni wierzcholek na starowy i poczatkowa odleglosc
	start--; koniec--; ostatni = start; s_ost = 0;
	//ustawiamy elementy zbioru T i wartosci oszacowane
	for(petla0 = 0; petla0 < ile_w; petla0++)
		{
		T[petla0] = 1;
		TJ[petla0] = DDL;
		}
	T[start] = 0;
	TJ[start] = 0;
	poprzednik[start] = DDL;

	do
		{
		//dla kazdego wierzcholka nalezacego do T staramy sie poprawic oszacowanie
		for(petla0 = 0; petla0 < ile_w; petla0++)
			{
			if((T[petla0])&& ((s_ost + siec[ostatni][petla0]) < TJ[petla0]))
				{
				TJ[petla0] = s_ost + siec[ostatni][petla0];
				poprzednik[petla0] = ostatni;
				}
			}
		//realizacja pomniejszania zbioru T
		minimum = DDL;
		for(petla0 = 0; petla0 < ile_w; petla0++)
			{
			if((T[petla0])&& (TJ[petla0] < minimum))
				{
				minimum = TJ[petla0];
				pozycja = petla0;
				}
			}
		T[pozycja] = 0;
		ostatni = pozycja;
		s_ost = TJ[ostatni];
		}
		while(T[koniec] == 1);
	//wypisanie wynikow na ekran
	//najpierw musimy odczytac z tabeli wlasciwa kolejnosc
	pozycja = 0; ostatni = koniec;
	do
		{
		sciezka[pozycja++] = ostatni;
		ostatni = poprzednik[ostatni];
		}
		while(ostatni != DDL);
	//i mozemy wypisac wszystkie dane na ekran
	cout << endl << "Rozwiazaniem jest sciezka: ";
	for(petla0 = (pozycja - 1); petla0 >=0; petla0--)
		cout << "[" << (sciezka[petla0] + 1) << "]";
	cout << endl << "O dlugosci: " << s_ost;
	//czy jeszcze inna sciezka
	cout << endl << endl << "Czy chcesz zbadac inna sciezke? [T/N]";
	klawisz = getch();
	}
	while((klawisz != 'n') && (klawisz != 'N'));
}
0

Dięki wielkie za algorytm!Zauważyłam jednak drobniutki błędzik, który akurat w moim grafie dał o sobie znać. Przy "poprawianiu oszacowania dla kazdego wierzchołka należącego do T" w warunku nie powinno być tak: if((T[petla0])&& ((s_ost + siec[ostatni][petla0]) < TJ[petla0])) ale tak: if((T[petla0])&& ((s_ost + siec[ostatni][petla0]) <= TJ[petla0])) mały blędzik jak już powiedziałam ale jednak posiedziaam sporo nad tym anim wymysliłam tą poprawkę :D
No cóż, w końcu jestem początkująca!Dzięki wielkie jeszcze raz!

// dla innych poczatkujacych, bierzcie przyklad z samodzielnego myslenia [mf]

1 użytkowników online, w tym zalogowanych: 0, gości: 1