亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? graph.cpp

?? 改進(jìn)的Dijkstra尋徑算法
?? CPP
字號:

#include "Graph.h"

using namespace Mido::Utility;

#define INFINITY 0xFFFFFFFF


Graph::Graph() : _N(0), _size(0)
{
}

Graph::Graph(const dag_t& array)
{
	_N = _size = array.size();
	_array.resize(_size);
	for(int i=0;i<_size;i++)
	{
		_array[i].resize(_size);
		for(int j=0;j<_size;j++)
			_array[i][j] = array[i][j];
	}
}

Graph::Graph(const double **array, unsigned N) : _N(N), _size(N)
{	
	_array.resize(_size);
	for(int i=0;i<_size;i++)
	{
		_array[i].resize(_size);
		for(int j=0;j<_size;j++)
			_array[i][j] = array[i][j];
	}
	
	//this->Output(); // for debug
}

Graph::~Graph()
{	
}

void Graph::Restart(const dag_t& array)
{
	_array.clear();

	_N = _size = array.size();
	_array.resize(_size);
	for(int i=0;i<_size;i++)
	{
		_array[i].resize(_size);
		for(int j=0;j<_size;j++)
			_array[i][j] = array[i][j];
	}

	//this->Output(); // for debug
}

void Graph::Restart(const double** array,unsigned N)
{
    _array.clear();

	_N = _size = N;
	_array.resize(_size);
	for(int i=0;i<_size;i++)
	{
		_array[i].resize(_size);
		for(int j=0;j<_size;j++)
			_array[i][j] = array[i][j];
	}
}

double Graph::Dijkstra( path_t& path )
{
	int* paths = new int[_size];
	double min = dijkstra(paths);
   if(min < 0) { delete[] paths; return -1;}

	// parse the shortest path	
	int i = _size - 1;	
	while(i>=0)
	{		
		path.push(i);
		i=paths[i];			
	}
	// push the start node
	path.push(0); 
	
	delete[] paths;
	return min;
}

double Graph::Dijkstra( unsigned start , unsigned end , path_t& path )
{
	if(end == start || start >= _size) return -1;

	int* paths = new int[_size];
	double min = dijkstra(paths,start,end);
    if(min < 0) { delete[] paths; return -1;}

	// parse the shortest path
	if(end > _size-1) end = _size - 1;
	int i = end;	
	while(i>=0)
	{		
		path.push(i);
		i=paths[i];			
	}
	// push the start node
	if(_array[start][path.top()]>=0)
		path.push(start);	
	else 
		{ delete[] paths; return -1;}

    delete[] paths;
	return min;
}

void Graph::Output(ostream& out)
{
	for(int i=0;i<_size;i++)
	{
		out.width(2);
		out << std::right << i << " ";
		for(int j=0;j<_size;j++)
		{
			out.width(10); //out.precision(8);
			out << std::right <<_array[i][j] <<" ";
		}
		out << endl;
	}
}

/*
    S       -- START node.
	T		-- END node
	Path[]  -- Path[i]=j indicates the previous node of node i is j. Path[i]=-1 indicates node i
	           has not previous node, e.g. START node. It could be expanded dynamically.
    Dist[]  -- store the lengths of the shortest pathes from START node to END node. It could be
			   expanded dynamically.Dist[i]=INFINITY indicates there is not a path from START
			   node to node i.
	Prime[] -- Prime[i] indicates node Prime[i] is the prime node of node i. Prime[i]=-1 indicates
	           the node i has not prime node.
	Base[]  -- In opposition to Prime[i], node Base[i] is the original node of node i, that is to say, 
	           node i is the prime node of node Base[i].

    S       -- 開始節(jié)點。
	T		-- 終止節(jié)點。
	Path[]  -- 存儲從開始節(jié)點到其他節(jié)點的最短路徑信息。核心思想是每個元素中存儲其最短
			   路徑中前一個節(jié)點的編號。在MS算法中,由于有向圖中擴(kuò)展節(jié)點的加入,此數(shù)組會
			   進(jìn)行動態(tài)擴(kuò)充。Path[i]=-1表示節(jié)點i無前驅(qū)節(jié)點。
    Dist[]  -- 存儲從開始節(jié)點到其他節(jié)點的最短距離值。同樣此數(shù)據(jù)也會進(jìn)行動態(tài)擴(kuò)充。
			   Dist[i]=INFINITY表示從開始節(jié)點到i節(jié)點沒有路徑相連。
    Prime[] -- 存儲某個節(jié)點的擴(kuò)展節(jié)點的編號。Prime[i]=-1表示節(jié)點i沒有擴(kuò)展節(jié)點。此數(shù)組
			   也會進(jìn)行動態(tài)擴(kuò)展。通過在Prime[]中尋找節(jié)點T的擴(kuò)展節(jié)點T`,T``,T```, ……,
			   然后在Path[]中依次求得這些擴(kuò)展節(jié)點對應(yīng)的最短路徑,即可以得到前k條最短路徑。
	Base[]  -- Prime[]是用來從基本節(jié)點出發(fā)尋找擴(kuò)展節(jié)點,而Base[]正好相反,它是用來記錄擴(kuò)展
	           節(jié)點對應(yīng)的原始節(jié)點。如果本來就是原始節(jié)點則對應(yīng)的值就是本身。
	
 */
int Graph::MSAforKSP( unsigned k ,  path_list& kpaths )
{	
	/* Initialize */	
	vector<int> Path, Prime, Base;
	vector<double> Dist;
	Path.resize(_size); 
	Prime.resize(_size);
	Base.resize(_size);
	Dist.resize(_size);
	for(int i=0;i<_size;i++)
	{ Prime[i] = -1; Base[i] = i; }
	
	/* Find the shortest path firstly */	
	if( dijkstra(&Path[0],&Dist[0]) < 0 ) return 0;
	path_t path; 
	int j = _size - 1;	
	while(j>=0)
	{		
		path.push(j); j=Path[j];			
	}
	kpaths.push_back(path); // store the shortest path

	/* Find the 2th - kth shortest paths */
	int ki = 1;
	while( ki < k )
	{
		/* Find the first node with more than a single incoming arc */
		unsigned nh = 0;
		while( path.size() )
		{
			unsigned node = path.top(); path.pop();
			int count = 0;
			for( int i=0; i<_size; i++ )
			{
				if( _array[i][node] >= 0 ) count++;
				if( count > 1 ) break;
			}
			
			if( count > 1 ) { nh = node; break; }
		}

		if( !nh ) break; // there is NOT an alternative path, exit!

		unsigned ni = 0;
		/* Add the first prime node to graph */
		if( Prime[nh] < 0 )
		{
			unsigned nh1 = addNode(nh,Path[nh]);

			/* compute the minimal distance from node 0 to nh1 */
			double min_dist = (unsigned)INFINITY;
			int min_node = -1;
			for(int i=0;i<_size-1;i++)
			{
				//cout << Dist[i] << " " << _array[i][nh1] << endl; // for debug
				if( Dist[i] + (unsigned)_array[i][nh1] < min_dist )
				{
					min_dist = Dist[i] + _array[i][nh1];
					min_node = i;
				}
			}
			
			Dist.push_back(min_dist);
			Path.push_back(min_node);
			Prime.push_back(-1);
			Prime[nh] = nh1;

			/* record the base node */
			unsigned basei = nh;
			while(basei != Base[basei])
				basei = Base[basei];
			Base.push_back(basei);

			if(path.size())
			{ ni = path.top(); path.pop(); }
		}
		/*  Get node ni, it must meet it's the first node following nh in path, but its prime node ni` is NOT in graph */
		else
		{
			while( path.size() )
			{
				ni = path.top(); path.pop();
				if(Prime[ni] < 0) break;				
			}
		}		

		/* Add the other prime nodes to graph */
		while(ni)
		{
			unsigned ni1 = addNode(ni,Path[ni]);
			if(Prime[Path[ni]]>=0)				
				_array[Prime[Path[ni]]][ni1] = _array[Path[ni]][ni];	// add the arc -- (ni-1`,ni`)			

			/* compute the minimal distance from node 0 to ni1 */
			double min_dist = (unsigned)INFINITY;
			int min_node = -1;
			for(int i=0;i<_size-1;i++)
			{
				//cout << Dist[i] << " " << _array[i][ni1] << endl; // for debug
				if( Dist[i] + (unsigned)_array[i][ni1] < min_dist )
				{
					min_dist = Dist[i] + _array[i][ni1];
					min_node = i;
				}
			}
			
			Dist.push_back(min_dist);
			Path.push_back(min_node);
			Prime.push_back(-1);
			Prime[ni] = ni1;

			/* record the base node */
			unsigned basei = ni;
			while(basei != Base[basei])
				basei = Base[basei];
			Base.push_back(basei);

			if( !path.size() ) break;
			ni = path.top(); path.pop();			
		}

		/* get the kth shortest path */			
		if( !ni ) ni = nh; // if nh is just the end node.
		path_t temp;		
		int j = Prime[ni];
		while(j>=0)
		{		
			path.push(j); temp.push(Base[j]); j=Path[j];
		}
		if(temp.size()<2) break; 
		kpaths.push_back(temp);  // store the kth shortest path

		ki++;
		//this->Output(); // for debug
	}	
	
	return ki;
}


/*
	Look out: Dijkstra algorithm doesn't assure the
	generated tree from graph is minimal generated tree.
*/
/// Look out: the returned paths doesn'n include the start node!
double Graph::dijkstra( int* paths , unsigned start , unsigned end )
{		int* Used = new int[_N];		   // label the used nodes, 0 - indicates not used.	double* Dist = new double[_N];     // store the min distances from start node to node indicated by current suffix.	/* Initialize */		unsigned i;	for(i=0;i<_N;i++)	{		paths[i]= -1;			Used[i] = 0;		Dist[i] = (_array[start][i] < 0.0) ? INFINITY : _array[start][i]; 	}		Used[start] = 1;		           // label the start node		unsigned count = 0;		while(count++ < _N)	{				int min_node = -1;		double min_dist = (unsigned)INFINITY;		/* Select */		for(i=0;i<_N;i++)		{			if(Used[i] > 0)continue;   // ignore the used node						if(Dist[i] < min_dist)			{				min_dist = Dist[i];				min_node = i;			}		}		if(min_dist == INFINITY)break;		/* Record shortest path from the current node to start node */		if(min_node >= 0)		{						Used[min_node]  = 1;			Dist[min_node]  = min_dist;					}		if(min_node >= (int)_N-1)break;		/* Adjust */		for(i=0;i<_N;i++)		{			if( Used[i] > 0)continue;  // ignore the used node			double w = (unsigned)_array[min_node][i]; //_array[min_node][i] < 0.0 ? INFINITY : _array[min_node][i];			if( min_dist + w < Dist[i] )			{				Dist[i] = min_dist + w;				paths[i] = min_node;			}		}       	}		double mdist = Dist[_N-1];	if( end != start && end < _N)		mdist = Dist[end];	delete[] Used;	delete[] Dist;	return (signed)mdist;// == INFINITY ? -1 : mdist;
}

double Graph::dijkstra( int* paths , double* dists )
{		int* Used = new int[_N]; 	       // label the used nodes, 0 - indicates not used.	double* Dist = dists;	/* Initialize */		unsigned i;	for(i=0;i<_N;i++)	{		paths[i]= -1;			Used[i] = 0;		Dist[i] = (_array[0][i] < 0.0) ? INFINITY : _array[0][i]; 	}		Used[0] = 1;		               // label the start node		unsigned count = 0;		while(count++ < _N)	{				int min_node = -1;		double min_dist = (unsigned)INFINITY;		/* Select */		for(i=0;i<_N;i++)		{			if(Used[i] > 0)continue;   // ignore the used node						if(Dist[i] < min_dist)			{				min_dist = Dist[i];				min_node = i;			}		}		if(min_dist == INFINITY)break;		/* Record shortest path from the current node to start node */		if(min_node >= 0)		{						Used[min_node]  = 1;			Dist[min_node]  = min_dist;					}		if(min_node >= (int)_N-1)break;		/* Adjust */		for(i=0;i<_N;i++)		{			if( Used[i] > 0)continue;  // ignore the used node			double w = (unsigned)_array[min_node][i];// < 0.0 ? INFINITY : _array[min_node][i];			if( min_dist + w < Dist[i] )			{				Dist[i] = min_dist + w;				paths[i] = min_node;			}		}       	}	delete[] Used;	return (signed)Dist[_N-1];// == INFINITY ? -1 : Dist[_N-1];
}

/*
	Here, using vector is more efficient than 2-dimension dynamic array.
*/
unsigned Graph::addNode(unsigned ni,int preni)
{
	vector<double> newRow;
	for(int i=0;i<_size;i++)
	{
		if(i != preni)
			_array[i].push_back(_array[i][ni]);
		else
			_array[i].push_back(-1);

		newRow.push_back(-1);
	}
	newRow.push_back(-1);
	_array.push_back(newRow);

	return _size++;
}

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品久久久久国产精品日日| 成人avav影音| 91麻豆精品国产91久久久久| 亚洲一区在线电影| 欧美精品一卡两卡| 免播放器亚洲一区| 久久这里只精品最新地址| 国产成人日日夜夜| 亚洲人亚洲人成电影网站色| 在线精品国精品国产尤物884a| 亚洲女同女同女同女同女同69| 欧美亚洲免费在线一区| 石原莉奈在线亚洲二区| 精品国产91九色蝌蚪| 成人黄页在线观看| 亚洲午夜一区二区三区| 欧美一区二视频| 国产精品一二三四区| 一区二区三区在线免费观看| 欧美精品自拍偷拍动漫精品| 狠狠色丁香久久婷婷综合丁香| 国产日韩亚洲欧美综合| 在线中文字幕不卡| 韩国精品免费视频| 中文字幕在线一区二区三区| 欧美猛男男办公室激情| 国产91丝袜在线观看| 亚洲成人免费电影| 久久久91精品国产一区二区三区| 色综合网色综合| 国内久久精品视频| 亚洲最大成人网4388xx| 久久久亚洲精品石原莉奈| 欧美性大战久久久| 国产69精品久久久久毛片| 亚洲不卡一区二区三区| 中文字幕精品三区| 欧美精品日韩一区| 播五月开心婷婷综合| 看电影不卡的网站| 亚洲美女区一区| 久久久久久久电影| 欧美精品一二三区| 97se亚洲国产综合自在线不卡| 日本午夜一本久久久综合| 成人免费在线视频观看| 2023国产精品| 91精品国产综合久久久久久| www.亚洲色图| 国产成人综合在线观看| 蜜桃一区二区三区四区| 亚洲国产欧美另类丝袜| 亚洲欧洲成人自拍| 久久精品网站免费观看| 欧美日韩成人一区| 在线亚洲免费视频| 99久久伊人久久99| 成人深夜福利app| 国产一区二区电影| 激情伊人五月天久久综合| 午夜伦理一区二区| 亚洲国产成人av网| 一区二区三区欧美久久| 亚洲人成亚洲人成在线观看图片 | 91丝袜高跟美女视频| 国产在线精品一区二区不卡了| 亚洲电影激情视频网站| 成人a免费在线看| 黄色小说综合网站| 毛片av一区二区| 日本va欧美va瓶| 日本中文在线一区| 美女网站视频久久| 蜜臀av性久久久久蜜臀aⅴ四虎 | 欧美日韩成人高清| 欧美日韩免费观看一区二区三区 | 欧美私模裸体表演在线观看| 成人午夜激情影院| 国产91对白在线观看九色| 国产乱淫av一区二区三区| 国产一区二区三区精品欧美日韩一区二区三区| 日韩电影在线一区二区三区| 日韩电影在线看| 蜜桃免费网站一区二区三区| 免费成人性网站| 国产一区二区三区免费| 国产黑丝在线一区二区三区| 国产成人在线视频网址| 高清不卡一二三区| 91亚洲国产成人精品一区二三 | 久久免费的精品国产v∧| 久久夜色精品一区| 欧美高清在线视频| 一区二区在线观看视频| 亚洲成人手机在线| 激情综合色播激情啊| 成人精品免费网站| 99久久久免费精品国产一区二区| 91视频精品在这里| 欧美日韩在线播放三区| 91精品国产综合久久精品麻豆| 日韩亚洲电影在线| 国产精品午夜在线| 亚洲精品高清在线| 麻豆精品在线视频| 不卡的av网站| 91精品国产福利| 国产精品女人毛片| 午夜激情久久久| 成人网页在线观看| 欧美日韩视频在线观看一区二区三区| 欧美日韩久久一区| 国产日韩精品一区二区三区在线| 亚洲三级在线免费观看| 日日摸夜夜添夜夜添国产精品 | 天天色综合天天| 精品一区二区精品| 91在线观看下载| 日韩一区二区不卡| 成人免费小视频| 韩国欧美国产一区| 欧美伊人精品成人久久综合97| 亚洲精品在线免费播放| 亚洲欧美日韩国产中文在线| 麻豆精品一二三| 色老头久久综合| 国产午夜精品美女毛片视频| 亚洲国产一区视频| 成人精品视频一区| 精品欧美久久久| 亚洲成人黄色影院| 波多野结衣精品在线| 日韩欧美国产一区二区在线播放| 亚洲视频在线观看一区| 精品一区二区三区视频| 欧美少妇一区二区| 国产精品国产馆在线真实露脸 | 国产尤物一区二区| 欧美久久久久久久久久| 亚洲天堂久久久久久久| 国产福利不卡视频| 欧美一级夜夜爽| 亚洲午夜视频在线| 91免费观看国产| 中文字幕国产一区二区| 九九视频精品免费| 欧美一区二区视频网站| 亚洲国产中文字幕在线视频综合| 成人av综合一区| 国产亚洲一区字幕| 国模一区二区三区白浆 | www国产成人| 蜜臀精品久久久久久蜜臀| 欧美性xxxxxxxx| 亚洲福利电影网| 欧美在线高清视频| 一区二区三区欧美在线观看| 9i看片成人免费高清| 国产精品久久久久久久久免费樱桃 | 欧美日韩在线播放三区四区| 亚洲免费看黄网站| 色婷婷精品大在线视频| 国产精品女主播在线观看| 成人中文字幕在线| 国产亚洲女人久久久久毛片| 国产一区二区精品久久99| 精品国产欧美一区二区| 极品少妇一区二区| 精品国产91亚洲一区二区三区婷婷 | 日本乱人伦aⅴ精品| 自拍偷在线精品自拍偷无码专区 | 欧美mv日韩mv| 激情六月婷婷久久| 久久午夜色播影院免费高清 | 国产很黄免费观看久久| 国产欧美日韩激情| 不卡的看片网站| 亚洲欧美日韩国产综合在线 | 666欧美在线视频| 美日韩一级片在线观看| 精品国产sm最大网站免费看| 国产盗摄一区二区三区| 中文字幕成人av| 91年精品国产| 午夜精品久久久久久久99水蜜桃 | 亚洲一级二级三级| 欧美三级韩国三级日本一级| 日韩国产欧美三级| 精品国产凹凸成av人网站| 粉嫩高潮美女一区二区三区| 中文字幕一区二| 欧美日韩中文字幕一区| 久久精品久久99精品久久| 久久久久国产精品麻豆| 99久久er热在这里只有精品66| 一区二区三区鲁丝不卡| 欧美一级久久久| 成人av免费观看| 日韩影视精彩在线| 国产亚洲婷婷免费|