Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Dec 9th, 2005, 4:37 PM   #1
groovicus
Programmer
 
Join Date: Nov 2004
Posts: 84
Rep Power: 5 groovicus is on a distinguished road
Dijkstra's Algorithm

Here is my implementation of Dijkstra's Algo.. It is a little rough, but it works as it is supposed to.

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <list>
using namespace std;

struct Edge{ int to; int wt; };

struct City{ string name; list<Edge> adj; };

class PathFinder{
private:
	map<string,int> name2idx;
	vector<City> city;
	
public:
	PathFinder(string fileName); //builds graph from file
	int minCost(string from, string to); //-1 if no path

private:  //helper methods==================
	
	typedef map<string,int>:: iterator Iter;	      //map iterator
	typedef list<Edge>::iterator eIter;			//list iterator

	int addEdge(int to, int wgt);				  //build graph
	int addCity(string from);				   //build graph
	int pushCity(string city);
	int pushEdge(string from, string to, int wgt);

};


#include "pathfinder.h"
#include <fstream> 
#include <iostream>


PathFinder::PathFinder(string fileName){

	ifstream fin(fileName.c_str());

	while(true){
		
		string from, to; 
		int wgt = 0;
        fin>>from>>to>>wgt;	 if(!fin) break;	

		//add cities
		pushCity(from);
		pushCity(to);

		//add edges
		pushEdge(from, to, wgt);

	}

	/*
	//check adjacencies test loop
	for(unsigned int i = 0; i< city.size(); i++){
		eIter begin = city[i].adj.begin();
		eIter end = city[i].adj.end();

		while( begin != end) {
			//get city from index number
			City ct = city[begin->to];
			//cout<<begin->to<<" can be reached from "<<city[i].name<<endl;
			++begin;
		}
	}
	*/
	//cout<<name2idx.size()<<"= ="<<city.size()<<endl;
	for(int i=0;i<city.size();i++){
		cout<<city[i].name<<": ";
		for(list<Edge>::iterator it=city[i].adj.begin();
	        it != city[i].adj.end(); it++)
		cout<<city[it->to].name<<","<<it->wt<<" ";
		cout<<endl;
	}
}

int PathFinder::minCost(string from, string to){
	//returns cheapest path or -1 if not found

	int MAX_INT= 2500000;
	bool once = true;
	int trueCount = 0;	 //infinite loop prevention (in theory)


	/* initialize arrays
	*/

	bool * isMarked = new bool[(int)city.size()];	 //true if marked
	for(int i = 0; i< (int)city.size(); i++){		 //init to false
		isMarked[i] = false;
	}

	int *cost = new int[(int)city.size()];			//travel cost
	for(int i = 0; i< (int)city.size(); i++){		//init to MAX_INT
		cost[i] = MAX_INT;
	}

	int curCityIndex = 0;

	/*//test loop
	for(int i = 0; i<100; i++){
			cout<<" City at i is "<<city[i].name<<endl;
	}
*/
	while (from != to){
		//get current city (from) index
		curCityIndex =name2idx.find(from)->second;
		cout<<"curcity=="<<from<<"=="<<endl;

 
		//set cost of initial starting city
		if(once){
			cost[curCityIndex]=0;			//sets initial cost to zero
			once = false;
			trueCount++;
		}

		/*******************UPDATE COSTS**********************/

		eIter begin = city[curCityIndex].adj.begin();
		eIter end = city[curCityIndex].adj.end();

		//if(city[curCityIndex].adj.size() == 0)return -1;

		while( begin != end && city[curCityIndex].adj.size() > 0 ) { //while not at end, and has adj.

			if(isMarked[begin->to]== false){

				int adj = begin->to;     //city to go to
				int weight = begin->wt;  //weighted cost
				
				if(cost[adj]  > cost[curCityIndex] + begin->wt){
					cost[adj] = cost[curCityIndex] + begin->wt;
			    }
			}
			++begin;
		}

		/****************FIND CHEAPEST NEXT********************/
		int cheapest = MAX_INT;
		int cheapIndex = MAX_INT;

		for(int i = 0; i< (int)city.size(); i++){
			

			if(cost[i]< cheapest && !isMarked[i]){
				cheapest = cost[i];
				cheapIndex = i;
				//from = city[i].name;

				//isMarked[i] = true;
				//trueCount++;

				//if(from == to && isMarked){
				//	return cost[i];
				//}
			}			
		}
		if(cheapIndex==MAX_INT)return -1;
		isMarked[cheapIndex]=true;
		from = city[cheapIndex].name;

	}

	return cost[name2idx.find(from)->second]; //if no path
	
}
//private helpers ====================




int PathFinder::pushEdge(string from, string to, int wgt){
	//post:push new edge

	Iter it = name2idx.find(to);
	Edge goTo;									
	goTo.to = it->second; 
	goTo.wt = wgt;
	
	city[name2idx.find(from)->second].adj.push_back(goTo);

	return 0;
}

int PathFinder::addCity(string from){
	//post: city is added to city and name2idx
	City start;									
	start.name = from;
	city.push_back(start);
	int thisI = (int)city.size()-1;
	//cout<<thisI<<"added city "<<from<<" idx="<<(int)name2idx.size()<<endl;
	name2idx.insert(make_pair(from,(int) name2idx.size()));

	return 0;
}

int PathFinder::pushCity(string city){
	//post: city is added to city and name2idx
	//      else return -1
	Iter it = name2idx.find(city);

	if( it==name2idx.end()) {
		addCity(city);	
		return 0;
	}

	return -1;				//if not added
}


//test program
int main(){
	PathFinder pf("flight.txt");
	while(true){
		string fr,to;
		cout<<"enter from to (q q to quit) ";cin>>fr>>to;
		if(fr=="q" && to=="q") break;
		cout<<pf.minCost(fr,to)<<endl;
	}
}

And a small test file (save as flight.txt)
alpha bravo 1
bravo charlie 2
bravo delta 4
bravo echo 8
charlie echo 5
charlie delta 7
delta echo 6

Please excuse the indents.. they are ugly as sin. Apparently that is what happens when they are imported from Visual C++..
__________________
HijackThis Team-SFDC
groovicus is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 8:42 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC