⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graph.cpp

📁 实现了图的搜索算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	int end = getVertexID(coor2);
	return BFS(start, end, tree);
}

BOOL Graph::DFS(int start, int end, Graph& tree)
{
	if(start>=0 && end>=0 && start<m_vertexs.size() && end<m_vertexs.size()){
		VerNode* pv1 = NULL, *pv2 = NULL;
		EdgeNode* pe = NULL;
		int coorp[2], coorc[2], parent, child, size;
		//初始化搜索树
		tree.clear();
		pv1= m_vertexs[start];
		tree.insertVertex(pv1->m_nCoor);
		//初始化开表和毕表
		m_open.clear();
		m_close.clear();
		clearVertexFlag();
		m_open.push_back(start);
		pv1->m_bInOpen = TRUE;
		//开始算法的运算过程
		while(m_open.size()>0){
			parent = m_open[0];//将n节点从开表中删除,放到毕表中
			m_open.pop_front();
			m_close.push_back(parent);
			pv1 = m_vertexs[parent];
			pv1->m_bInClose = TRUE;
			pv1->m_bInOpen = FALSE;
			if(parent == end){
				//找到目标节点
				return TRUE;
			}else{
				//扩展n节点
				size = pv1->m_edgeOut.size();
				coorp[0] = pv1->m_nCoor[0];
				coorp[1] = pv1->m_nCoor[1];
				for(int i = 0; i<size; i++){
					pe = pv1->m_edgeOut[i];
					child = pe->m_pVerTo->m_nID;
					pv2 = m_vertexs[child];
					coorc[0] = pv2->m_nCoor[0];
					coorc[1] = pv2->m_nCoor[1];
					if(!pv2->m_bInClose && !pv2->m_bInOpen){
						//新的节点没有出现在open或者close表中
						tree.insertVertex(coorc);
						tree.insertEdge(coorp, coorc);
						//对于深度优先搜索来说,将扩展的节点放到open表的前面
						m_open.push_front(child);
						pv2->m_bInOpen = TRUE;
					}
				}
			}
		}
	}		
	return FALSE;
}

BOOL Graph::BFS(int start, int end, Graph& tree)
{
	if(start>=0 && end>=0 && start<m_vertexs.size() && end<m_vertexs.size()){
		VerNode* pv1 = NULL, *pv2 = NULL;
		EdgeNode* pe = NULL;
		int coorp[2], coorc[2], parent, child, size;
		//初始化搜索树
		tree.clear();
		pv1= m_vertexs[start];
		tree.insertVertex(pv1->m_nCoor);
		//初始化开表和毕表
		m_open.clear();
		m_close.clear();
		clearVertexFlag();
		m_open.push_back(start);
		pv1->m_bInOpen = TRUE;
		//开始算法的运算过程
		while(m_open.size()>0){
			parent = m_open[0];//将n节点从开表中删除,放到毕表中
			m_open.pop_front();
			m_close.push_back(parent);
			pv1 = m_vertexs[parent];
			pv1->m_bInClose = TRUE;
			pv1->m_bInOpen = FALSE;
			if(parent == end){
				//找到目标节点
				return TRUE;
			}else{
				//扩展n节点
				size = pv1->m_edgeOut.size();
				coorp[0] = pv1->m_nCoor[0];
				coorp[1] = pv1->m_nCoor[1];
				for(int i = 0; i<size; i++){
					pe = pv1->m_edgeOut[i];
					child = pe->m_pVerTo->m_nID;
					pv2 = m_vertexs[child];
					coorc[0] = pv2->m_nCoor[0];
					coorc[1] = pv2->m_nCoor[1];
					if(!pv2->m_bInClose && !pv2->m_bInOpen){
						//新的节点没有出现在open或者close表中
						tree.insertVertex(coorc);
						tree.insertEdge(coorp, coorc);
						//对于广度优先搜索来说,将扩展的节点放到open表的后面
						m_open.push_back(child);
						pv2->m_bInOpen = TRUE;
					}
				}
			}
		}
	}		
	return FALSE;
}

BOOL Graph::Dijkstra(int start, int end, Graph& tree)
{
	if(start>=0 && end>=0 && start<m_vertexs.size() && end<m_vertexs.size()){
		VerNode* pv1 = NULL, *pv2 = NULL;
		EdgeNode* pe = NULL;
		int coorp[2], coorc[2], parent, child, size;
		float newg = 0.0f, newf = 0.0f;//新的估价函数值
		int idtree = 0;//节点在tree中的索引值
		VerNode* pvtree = NULL;//节点在tree中的指针
		EdgeNode* petree = NULL;//边在tree中的指针

		//初始化搜索树
		tree.clear();
		pv1= m_vertexs[start];
		tree.insertVertex(pv1->m_nCoor);
		//初始化开表和毕表
		m_open.clear();
		m_close.clear();
		clearVertexFlag();
		m_open.push_back(start);
		pv1->m_bInOpen = TRUE;
		pv1->m_g = 0.0f;//计算起始点的估价函数值
		pv1->m_f = pv1->m_g;
		//开始算法的运算过程
		while(m_open.size()>0){
			parent = m_open[0];//得到当前节点,并放到毕表中;
			m_open.pop_front();
			m_close.push_back(parent);
			pv1 = m_vertexs[parent];
			pv1->m_bInClose = TRUE;
			pv1->m_bInOpen = FALSE;
			if(parent == end){
				//找到目标节点
				return TRUE;
			}else{
				//扩展n节点
				size = pv1->m_edgeOut.size();
				coorp[0] = pv1->m_nCoor[0];
				coorp[1] = pv1->m_nCoor[1];
				for(int i = 0; i<size; i++){
					//得到扩展节点的属性(节点的ID,节点的指针)
					pe = pv1->m_edgeOut[i];
					child = pe->m_pVerTo->m_nID;
					pv2 = m_vertexs[child];
					coorc[0] = pv2->m_nCoor[0];
					coorc[1] = pv2->m_nCoor[1];
					//计算新扩展的节点的估价函数值
					//新的估价函数 = 节点pv1的估价函数值 + 边(pv1, pv2)的权值
					newg = pv1->m_g+pe->m_nWeight;
					newf = newg;
					if(!pv2->m_bInClose && !pv2->m_bInOpen){
						//新的节点没有出现在open或者close表中
						pv2->m_f = newf;//记录新的节点的估价值
						pv2->m_g = newg;
						//更新搜索图
						tree.insertVertex(coorc);
						tree.insertEdge(coorp, coorc);
						//新节点放到open表中
						insertOpen(child);
						pv2->m_bInOpen = TRUE;
					}else if(pv2->m_bInOpen){
						//节点pv2出现在open表中
						if(newf<pv2->m_f){
							pv2->m_f = newf;//更新节点pv2的估价值
							pv2->m_g = newg;
							//重新标定指针
							idtree = tree.getVertexID(coorc);
							pvtree = tree.m_vertexs[idtree];
							for(int k = 0; k<pvtree->m_edgeIn.size(); k++){
								petree = pvtree->m_edgeIn[k];
								tree.deleteEdge(petree->m_pVerFrom->m_nID, pvtree->m_nID);
							}
							tree.insertEdge(coorp, coorc);
							//更新open表中的内容
							updateOpen();
						}
					}else if (pv2->m_bInClose) {
						//节点pv2出现在close表中
						if(newf<pv2->m_f){
							pv2->m_f = newf;//更新节点pv2的估价值
							pv2->m_g = newg;
							//重新标定指针
							idtree = tree.getVertexID(coorc);
							pvtree = tree.m_vertexs[idtree];
							for(int k = 0; k<pvtree->m_edgeIn.size(); k++){
								petree = pvtree->m_edgeIn[k];
								tree.deleteEdge(petree->m_pVerFrom->m_nID, pvtree->m_nID);
							}
							tree.insertEdge(coorp, coorc);
							//将节点pv2重新放回open表中
							insertOpen(child);
							pv2->m_bInOpen = TRUE;
							pv2->m_bInClose = FALSE;
						}
					}
				}
				//以上为扩展节点n的操作
			}
		}
	}		
	return FALSE;
}

float Graph::A_star_h(int n, int end)
{
	//A*算法的启发函数
	//n为当前的节点,end为终点
	VerNode* pv1 = m_vertexs[n];
	VerNode* pv2 = m_vertexs[end];
	float d = sqrt(pow(pv1->m_nCoor[0]-pv2->m_nCoor[0], 2)+pow(pv1->m_nCoor[1]-pv2->m_nCoor[1], 2));
//	float d = fabs(pv1->m_nCoor[0]-pv2->m_nCoor[0])+fabs(pv1->m_nCoor[1]-pv2->m_nCoor[1]);
	return d;
}

BOOL Graph::A_star(int start, int end, Graph& tree)
{
	if(start>=0 && end>=0 && start<m_vertexs.size() && end<m_vertexs.size()){
		VerNode* pv1 = NULL, *pv2 = NULL;
		EdgeNode* pe = NULL;
		int coorp[2], coorc[2], parent, child, size;
		float newg = 0.0f, newf = 0.0f;//新的估价函数值
		int idtree = 0;//节点在tree中的索引值
		VerNode* pvtree = NULL;//节点在tree中的指针
		EdgeNode* petree = NULL;//边在tree中的指针

		//初始化搜索树
		tree.clear();
		pv1= m_vertexs[start];
		tree.insertVertex(pv1->m_nCoor);
		//初始化开表和毕表
		m_open.clear();
		m_close.clear();
		clearVertexFlag();
		m_open.push_back(start);
		pv1->m_bInOpen = TRUE;
		pv1->m_g = 0.0f;//计算起始点的估价函数值
		pv1->m_f = pv1->m_g+A_star_h(start, end);
		//开始算法的运算过程
		while(m_open.size()>0){
			parent = m_open[0];//得到当前节点,并放到毕表中;
			m_open.pop_front();
			m_close.push_back(parent);
			pv1 = m_vertexs[parent];
			pv1->m_bInClose = TRUE;
			pv1->m_bInOpen = FALSE;
			if(parent == end){
				//找到目标节点
				return TRUE;
			}else{
				//扩展n节点
				size = pv1->m_edgeOut.size();
				coorp[0] = pv1->m_nCoor[0];
				coorp[1] = pv1->m_nCoor[1];
				for(int i = 0; i<size; i++){
					//得到扩展节点的属性(节点的ID,节点的指针)
					pe = pv1->m_edgeOut[i];
					child = pe->m_pVerTo->m_nID;
					pv2 = m_vertexs[child];
					coorc[0] = pv2->m_nCoor[0];
					coorc[1] = pv2->m_nCoor[1];
					//计算新扩展的节点的估价函数值
					//新的估价函数 = 节点pv1的估价函数值 + 边(pv1, pv2)的权值
					newg = pv1->m_g+pe->m_nWeight;
					newf = newg+A_star_h(child, end);
					if(!pv2->m_bInClose && !pv2->m_bInOpen){
						//新的节点没有出现在open或者close表中
						pv2->m_f = newf;//记录新的节点的估价值
						pv2->m_g = newg;
						//更新搜索图
						tree.insertVertex(coorc);
						tree.insertEdge(coorp, coorc);
						//新节点放到open表中
						insertOpen(child);
						pv2->m_bInOpen = TRUE;
					}else if(pv2->m_bInOpen){
						//节点pv2出现在open表中
						if(newf<pv2->m_f){
							pv2->m_f = newf;//更新节点pv2的估价值
							pv2->m_g = newg;
							//重新标定指针
							idtree = tree.getVertexID(coorc);
							pvtree = tree.m_vertexs[idtree];
							for(int k = 0; k<pvtree->m_edgeIn.size(); k++){
								petree = pvtree->m_edgeIn[k];
								tree.deleteEdge(petree->m_pVerFrom->m_nID, pvtree->m_nID);
							}
							tree.insertEdge(coorp, coorc);
							//更新open表中的内容
							updateOpen();
						}
					}else if (pv2->m_bInClose) {
						//节点pv2出现在close表中
						if(newf<pv2->m_f){
							pv2->m_f = newf;//更新节点pv2的估价值
							pv2->m_g = newg;
							//重新标定指针
							idtree = tree.getVertexID(coorc);
							pvtree = tree.m_vertexs[idtree];
							for(int k = 0; k<pvtree->m_edgeIn.size(); k++){
								petree = pvtree->m_edgeIn[k];
								tree.deleteEdge(petree->m_pVerFrom->m_nID, pvtree->m_nID);
							}
							tree.insertEdge(coorp, coorc);
							//将节点pv2重新放回open表中
							insertOpen(child);
							pv2->m_bInOpen = TRUE;
							pv2->m_bInClose = FALSE;
						}
					}
				}
				//以上为扩展节点n的操作
			}
		}
	}		
	return FALSE;
}

void Graph::insertOpen(int vnode)
{
	//往open表中插入新的节点,并按照估价函数进行排序
	int size = m_open.size();
	VerNode* pv1 = m_vertexs[vnode];
	VerNode* pv2 = NULL;
	if(size>0){
		int index = -1; 
		for(int i = 0; i<size; i++){
			pv2 = m_vertexs[m_open[i]];
			if(pv1->m_f<=pv2->m_f){
				index = i;
				break;
			}
		}
		if(index>=0){
			m_open.insert(m_open.begin()+index, vnode);
		}else{
			m_open.push_back(vnode);
		}
	}else{
		m_open.push_back(vnode);
	}
}

void Graph::updateOpen()
{
	//更新OPEN表中的数据,前提是只有一个数据变化
	int size = m_open.size();
	VerNode *pv1, *pv2;
	int index = -1, temp;
	for(int i = 0; i<size-1; i++){
		pv1 = m_vertexs[m_open[i]];
		pv2 = m_vertexs[m_open[i+1]];
		if(pv1->m_f>pv2->m_f){
			index = i;
			temp = m_open[i];
			m_open[i] = m_open[i+1];
			m_open[i+1] = temp;
			break;
		}
	}

	if(index>=0){
		for(int i = index+1; i<size-1; i++){
			pv1 = m_vertexs[m_open[i]];
			pv2 = m_vertexs[m_open[i+1]];
			if(pv1->m_f>pv2->m_f){
				temp = m_open[i];
				m_open[i] = m_open[i+1];
				m_open[i+1] = temp;
			}else{
				break;
			}
		}

		for(i = index; i>0; i--){
			pv1 = m_vertexs[m_open[i]];
			pv2 = m_vertexs[m_open[i-1]];
			if(pv1->m_f<pv2->m_f){
				temp = m_open[i];
				m_open[i] = m_open[i-1];
				m_open[i-1] = temp;
			}else{
				break;
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -