Commit 29f1f6e6 authored by 刘乐's avatar 刘乐

1,有向图代码

parent a0d30126
#include "CivGraphFactory.h"
#include "CivGraphList.h"
#include "CivDbConn.h"
#include "CivPgConn.h"
CivGraphFactory::CivGraphFactory()
{
}
bool CivGraphFactory::createGraph(CivDbConn* dbConn, ALGraph<CivGraphJunction, CivGraphEdage>* graph)
{
if (dbConn == nullptr)
return false;
if (graph == nullptr)
return false;
// 顶点坐标
CivCoordinates coords;
dbConn->getCoordinates(coords);
std::list<CivCoordinates::CoordTable> coordTableLis = coords.mTables;
std::list<CivCoordinates::CoordTable>::iterator iter;
for (iter = coordTableLis.begin(); iter != coordTableLis.end(); iter++)
{
CivCoordinates::CoordTable coordTable = *iter;
// 插入顶点数据
CivGraphJunction graphJunction(coordTable.ID, coordTable.XCoord, coordTable.YCoord);
graph->insertAVertex(graphJunction);
}
// 管段
CivPipe civPipe;
dbConn->getPipe(civPipe);
std::list<CivPipe::PipesTable> pipesTableLis = civPipe.mTables;
std::list<CivPipe::PipesTable>::iterator pIter;
for (pIter = pipesTableLis.begin(); pIter != pipesTableLis.end(); pIter++)
{
CivPipe::PipesTable pipeTable = *pIter;
// 获取管段起点坐标
CivGraphJunction graphJunction1(pipeTable.Node1);
int index1 = graph->getVertexIndex(graphJunction1);
CivGraphJunction sStartjuction = graph->getData(index1);
// 获取管段终点坐标值
CivGraphJunction graphJunction2(pipeTable.Node2);
int index2 = graph->getVertexIndex(graphJunction2);
CivGraphJunction endJunction = graph->getData(index2);
CivGraphEdage edAge(pipeTable.ID, pipeTable.Length, { sStartjuction.getXCoord(),sStartjuction.getYCoord(),endJunction.getXCoord(),endJunction.getYCoord()});
graph->insertAEdge(sStartjuction, endJunction, edAge);
}
return true;
}
\ No newline at end of file
#pragma once
#include "CivHydDataType.h"
// 声明模板图类型
template <class VertexType, class EdgeType> class ALGraph;
class CivDbConn;
class CivGraphFactory
{
public:
CivGraphFactory();
/**
*@brief 根据水力模型管网数据创建有向图
*@param dbConn 数据库连接
*@param graph 有向图
*/
bool createGraph(CivDbConn* dbConn, ALGraph<CivGraphJunction, CivGraphEdage>* graph);
};
#include "CivGraphList.h"
#include "CivPgConn.h"
#include "CivDbConn.h"
#include "CivHydDataType.h"
template <class VertexType, class EdgeType>
ALGraph<VertexType, EdgeType>::ALGraph()
......@@ -9,20 +10,52 @@ ALGraph<VertexType, EdgeType>::ALGraph()
}
template <class VertexType, class EdgeType>
void ALGraph<VertexType, EdgeType>::createGraph(CivDbConn* dbConn)
void ALGraph<VertexType, EdgeType>::BFS(VertexType vertexName, int visit[])
{
if (dbConn == nullptr)
return;
// 获取输入顶点索引
int vi = getVertexIndex(vertexName);
if (-1 == v1)
{
cerr << "There is no vertex " << endl;
return false;
}
int vi = 0;
Edge<EdgeType>* edageNext;
// 初始化队列
std::queue<int> Q;
Q.push(node);
visit[vi] = 1;
while (!Q.empty()) {
int node = Q.front();
Q.pop();
edageNext = mVertexArray.at(node)..pAdjEdges;
while (edageNext)
{
// 未访问过的放入队列
if (!visit[edageNext->nDestVertex])
{
visit[edageNext->nDestVertex] = 1;
Q.push(edageNext->nDestVertex);
}
// 后移
edageNext = edageNext->pNextEdge;
}
}
}
template <class VertexType, class EdgeType>
ALGraph<VertexType, EdgeType>::~ALGraph()
{
for (auto iter = m_vertexArray.begin(); iter != m_vertexArray.end(); iter++)
for (auto iter = mVertexArray.begin(); iter != mVertexArray.end(); iter++)
{
Edge<weight>* p = iter->pAdjEdges;
Edge<EdgeType>* p = iter->pAdjEdges;
while (NULL != p)
{
iter->pAdjEdges = p->pNextEdge;
......@@ -30,9 +63,9 @@ ALGraph<VertexType, EdgeType>::~ALGraph()
p = iter->pAdjEdges;
}
}
if (!m_vertexArray.empty())
if (!mVertexArray.empty())
{
m_vertexArray.clear();
mVertexArray.clear();
}
}
......@@ -40,14 +73,14 @@ template <class VertexType, class EdgeType>
bool ALGraph<VertexType, EdgeType>::insertAVertex(IN const VertexType& vertexName)
{
Vertex<VertexType, EdgeType> VertexInstance(vertexName, NULL);
m_vertexArray.push_back(VertexInstance);
mVertexArray.push_back(VertexInstance);
return true;
}
template <class VertexType, class EdgeType>
bool ALGraph<VertexType, EdgeType>::insertAEdge(IN const VertexType vertexName1,
IN const VertexType vertexName2, IN const EdgeType edgeWeight)
bool ALGraph<VertexType, EdgeType>::insertAEdge(IN const VertexType& vertexName1,
IN const VertexType& vertexName2, IN const EdgeType& edgeWeight)
{
int v1 = getVertexIndex(vertexName1);
if (-1 == v1)
......@@ -63,7 +96,7 @@ bool ALGraph<VertexType, EdgeType>::insertAEdge(IN const VertexType vertexName1,
return false;
}
Edge<weight>* p = m_vertexArray.at(v1).pAdjEdges;
Edge<EdgeType>* p = mVertexArray.at(v1).pAdjEdges;
while (p != NULL && p->nDestVertex != v2)
{
p = p->pNextEdge;
......@@ -71,15 +104,15 @@ bool ALGraph<VertexType, EdgeType>::insertAEdge(IN const VertexType vertexName1,
if (NULL == p)
{
p = new Edge<weight>(v2, edgeWeight, m_vertexArray.at(v1).pAdjEdges);
m_vertexArray.at(v1).pAdjEdges = p;
p = new Edge<EdgeType>(v2, edgeWeight, mVertexArray.at(v1).pAdjEdges);
mVertexArray.at(v1).pAdjEdges = p;
return true;
}
if (v2 == p->nDestVertex)
{
Edge<weight>* q = p;
p = new Edge<weight>(v2, edgeWeight, q->pNextEdge);
Edge<EdgeType>* q = p;
p = new Edge<EdgeType>(v2, edgeWeight, q->pNextEdge);
q->pNextEdge = p;
return true;
}
......@@ -105,7 +138,7 @@ bool ALGraph<VertexType, EdgeType>::removeAEdge(IN const VertexType& vertexName1
return false;
}
Edge<EdgeType>* p = m_vertexArray.at(v1).pAdjEdges;
Edge<EdgeType>* p = mVertexArray.at(v1).pAdjEdges;
Edge<EdgeType>* q = NULL;
while (p != NULL && p->nDestVertex != v2)
{
......@@ -140,15 +173,15 @@ bool ALGraph<VertexType, EdgeType>::removeAEdge(IN const VertexType& vertexName1
template <class VertexType, class EdgeType>
EdgeType ALGraph<VertexType, EdgeType>::getEdgeWeight(IN const Edge<EdgeType>* pEdge)
{
return pEdge->edgeWeight;
return pEdge->edgeObj;
}
template <class VertexType, class EdgeType>
void ALGraph<VertexType, EdgeType>::getVertexEdgeWeight(IN const int v1, OUT vector<EdgeType>& DistanceArray)
{
Edge<weight>* p = m_vertexArray.at(v1).pAdjEdges;
Edge<EdgeType>* p = mVertexArray.at(v1).pAdjEdges;
int prevIndex = -1;
weight tmp;
EdgeType tmp;
while (NULL != p)
{
......@@ -172,8 +205,8 @@ void ALGraph<VertexType, EdgeType>::getVertexEdgeWeight(IN const int v1, OUT vec
}
template <class VertexType, class EdgeType>
EdgeType ALGraph<VertexType, EdgeType>::getMinWeight(IN const VertexType vertexName1,
IN const VertexType vertexName2)
EdgeType ALGraph<VertexType, EdgeType>::getMinWeight(IN const VertexType& vertexName1,
IN const VertexType& vertexName2)
{
Edge<EdgeType>* pEdge = NULL;
int v1 = getVertexIndex(vertexName1);
......@@ -190,7 +223,7 @@ EdgeType ALGraph<VertexType, EdgeType>::getMinWeight(IN const VertexType vertexN
return false;
}
Edge<EdgeType>* p = m_vertexArray.at(v1).pAdjEdges;
Edge<EdgeType>* p = mVertexArray.at(v1).pAdjEdges;
while (p != NULL && p->nDestVertex != v2)
{
p = p->pNextEdge;
......@@ -198,7 +231,7 @@ EdgeType ALGraph<VertexType, EdgeType>::getMinWeight(IN const VertexType vertexN
if (NULL == p)
{
pEdge = NULL;
return weight(0);
return EdgeType(0);
}
EdgeType tmp = getEdgeWeight(p);
pEdge = p;
......@@ -214,10 +247,10 @@ EdgeType ALGraph<VertexType, EdgeType>::getMinWeight(IN const VertexType vertexN
return tmp;
}
template <class VertexType, class EdgeType>
int ALGraph<VertexType, EdgeType>::getVertexIndex(IN const VertexType vertexName)
template <class VertexType, class EdgeType>
int ALGraph<VertexType, EdgeType>::getVertexIndex(IN const VertexType& vertexName)
{
for (int i = 0; i < m_vertexArray.size(); i++)
for (int i = 0; i < mVertexArray.size(); i++)
{
if (vertexName == getData(i))
{
......@@ -230,17 +263,17 @@ int ALGraph<VertexType, EdgeType>::getVertexIndex(IN const VertexType vertexName
template <class VertexType, class EdgeType>
int ALGraph<VertexType, EdgeType>::getVertexNumber()
{
return m_vertexArray.size();
return mVertexArray.size();
}
template <class VertexType, class EdgeType>
VertexType ALGraph<VertexType, EdgeType>::getData(IN int index)
{
return m_vertexArray.at(index).vertexName;
return mVertexArray.at(index).mVertex;
}
template <class VertexType, class EdgeType>
int ALGraph<VertexType, EdgeType>::Dijkstra(IN const VertexType vertexName1)
int ALGraph<VertexType, EdgeType>::Dijkstra(IN const VertexType& vertexName1)
{
int sourceIndex = getVertexIndex(vertexName1);
if (-1 == sourceIndex)
......@@ -258,8 +291,8 @@ int ALGraph<VertexType, EdgeType>::Dijkstra(IN const VertexType vertexName1)
//the array to record the distance from vertex1
vector<EdgeType> vecDistanceArray;
vecDistanceArray.assign(nVertexNo, weight(INT_MAX));
vecDistanceArray[sourceIndex] = weight(0);
vecDistanceArray.assign(nVertexNo, EdgeType(INT_MAX));
vecDistanceArray[sourceIndex] = EdgeType(0);
//prev array to record the previous vertex
vector<int> vecPrevVertex;
......@@ -271,7 +304,7 @@ int ALGraph<VertexType, EdgeType>::Dijkstra(IN const VertexType vertexName1)
while (1)
{
EdgeType minWeight = weight(INT_MAX);
EdgeType minWeight = EdgeType(INT_MAX);
vFrom = sourceIndex;
vTo = -1;
for (int i = 0; i < nVertexNo; i++)
......@@ -288,7 +321,7 @@ int ALGraph<VertexType, EdgeType>::Dijkstra(IN const VertexType vertexName1)
}
vecIncludeArray[vFrom] = true;
Edge<EdgeType>* p = m_vertexArray[vFrom].pAdjEdges;
Edge<EdgeType>* p = mVertexArray[vFrom].pAdjEdges;
while (NULL != p)
{
EdgeType wFT = p->edgeWeight;
......@@ -339,7 +372,7 @@ ostream& operator<<(OUT ostream& out, IN ALGraph<VertexType, EdgeType>& graphIn
VertexType x1 = graphInstance.getData(i);
out << x1 << ": ";
Edge<EdgeType>* p = graphInstance.m_vertexArray.at(i).pAdjEdges;
Edge<EdgeType>* p = graphInstance.mVertexArray.at(i).pAdjEdges;
while (NULL != p)
{
out << "(" << x1 << "," << graphInstance.getData(p->nDestVertex) << "," << p->edgeWeight << ") ";
......@@ -348,4 +381,4 @@ ostream& operator<<(OUT ostream& out, IN ALGraph<VertexType, EdgeType>& graphIn
out << endl;
}
return out;
}
}
\ No newline at end of file
......@@ -12,34 +12,34 @@ using namespace std;
class CivDbConn;
/**
*@brief 边结构体模板
*@brief 边表结点
*@param weight 权重类型
*/
template <class EdgeType>
struct Edge
{
int nDestVertex; // 目标节点个数
int nDestVertex; // 该边所指向的顶点位置
EdgeType edgeObj; // 边的属性值对象
Edge<EdgeType>* pNextEdge; // 连接下一条
Edge<EdgeType>* pNextEdge; // 连接下一条弧的指针
Edge(int d, weight c, Edge<EdgeType>* p = NULL)
Edge(int d, EdgeType c, Edge<EdgeType>* p = NULL)
:nDestVertex(d), edgeObj(c), pNextEdge(p)
{}
};
/**
*@brief 节点结构体模板
*@param vertextype 节点类型
*@param weight 权重类型
*@brief 邻接表中表的顶点
*@param VertexType 节点信息
*@param EdgeType 弧信息
*/
template <class VertexType, class EdgeType>
template <class VertexType, class EdgeType>
struct Vertex
{
VertexType mVertex;
VertexType mVertex; // 顶点信息
Edge<EdgeType>* pAdjEdges;
Edge<EdgeType>* pAdjEdges; // 指向第一条依附该顶点的弧
Vertex(VertexType x, Edge<EdgeType>* p = NULL)
:mVertex(x), pAdjEdges(p)
......@@ -56,13 +56,10 @@ public:
explicit ALGraph();
~ALGraph();
/**
*@brief 根据数库管网表生成图数据
*/
void createGraph(CivDbConn* dbConn);
public:
void BFS(VertexType vetexType, int visit[]);
/**
*@brief 往图中插入一个节点
*@param vertexName 节点值
......@@ -75,7 +72,7 @@ public:
*@param vertexName2 节点对象2
*@param edge 边
*/
bool insertAEdge(IN const VertexType vertexName1, IN const VertexType vertexName2, IN const EdgeType edge);
bool insertAEdge(IN const VertexType& vertexName1, IN const VertexType& vertexName2, IN const EdgeType& edge);
/**
*@brief 移除两个节点的边
......@@ -90,32 +87,38 @@ public:
*@param vertexName1 节点1
*@param vertexName2 节点2
*/
EdgeType getMinWeight(IN const VertexType vertexName1, IN const VertexType vertexName2);
EdgeType getMinWeight(IN const VertexType& vertexName1, IN const VertexType& vertexName2);
/**
*@brief 获取两个节点之间连接的最小权重值
*@param vertexName1 节点1
*@param vertexName2 节点2
*/
int getVertexIndex(IN const VertexType vertexName);
int getVertexIndex(IN const VertexType& vertexName);
/**
*@brief 获取顶点数据
*/
int getVertexNumber();
/**
*@brief 根据索引获取顶点数据
*@param index 索引值
*/
VertexType getData(IN int index);
int Dijkstra(IN const VertexType vertexName1);
int Dijkstra(IN const VertexType& vertexName1);
void DijkstraPrint(IN int index, IN int sourceIndex, IN vector<int> vecPreVertex);
friend ostream& operator<<(OUT ostream& out, IN const ALGraph<VertexType, EdgeType>& graphInstance);
public:
private:
EdgeType getEdgeWeight(IN const Edge<EdgeType>* pEdge);
void getVertexEdgeWeight(IN const int v1, OUT vector<EdgeType>& DistanceArray);
vector< Vertex<VertexType, EdgeType> > m_vertexArray;
vector<Vertex<VertexType, EdgeType> > mVertexArray; // 节点数组
};
......
#include "CivHydDataType.h"
CivGraphJunction::CivGraphJunction(std::string sN)
: mSN(sN)
{
}
CivGraphJunction::CivGraphJunction(std::string sN, std::string xCoord, std::string yCoord)
:mSN(sN),mXCoord(xCoord),mYCoord(yCoord)
{
}
bool CivGraphJunction::operator== (const CivGraphJunction& edage)
{
return mSN == edage.mSN;
}
CivGraphEdage::CivGraphEdage(std::string sn, std::string length, std::vector<std::string> position)
{
mSN = sn;
mLength = length;
if (position.size() != 5)
return;
mStartX = position[0];
mStartY = position[1];
mEndX = position[2];
mEndY = position[3];
}
bool CivGraphEdage::operator== (const CivGraphEdage& edage)
{
return mLength == edage.mLength;
}
bool CivGraphEdage::operator> (const CivGraphEdage& edage)
{
return mLength > edage.mLength;
}
bool CivGraphEdage::operator< (const CivGraphEdage& edage)
{
return mLength < edage.mLength;
}
bool CivGraphEdage::operator!= (const CivGraphEdage& edage)
{
return mLength != edage.mLength;
}
\ No newline at end of file
#pragma once
#include <string>
#include <vector>
/**
节点
*/
class CivGraphJunction
{
public:
explicit CivGraphJunction(std::string sN);
explicit CivGraphJunction(std::string sN, std::string xCoord, std::string yCoord);
bool operator== (const CivGraphJunction& edage);
void setSn(const std::string& sn) { mSN = sn; }
std::string getSn() { return mSN; }
void setXCoord(std::string xCoord) { mXCoord = xCoord; }
std::string getXCoord() { return mXCoord; }
void setYCoord(std::string yCoord) { mXCoord = yCoord; }
std::string getYCoord() { return mYCoord; }
private:
std::string mSN; // 本点号,
std::string mXCoord; // 横坐标
std::string mYCoord; // 纵坐标
};
/*
*/
class CivGraphEdage
{
public:
/**
*@brief 边构造函数
*@param sn 编号,
*@param length 管长
*@param position 注意顺序,[length, startx, starty, endx, endy]
*/
explicit CivGraphEdage(std::string sn, std::string length, std::vector<std::string> position);
bool operator== (const CivGraphEdage& edage);
bool operator> (const CivGraphEdage& edage);
bool operator< (const CivGraphEdage& edage);
bool operator!= (const CivGraphEdage& edage);
private:
std::string mSN;// 编号
std::string mLength; // 管长
std::string mStartX;
std::string mStartY;
std::string mEndX;
std::string mEndY;
};
......@@ -146,10 +146,14 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="CivGraphFactory.h" />
<ClInclude Include="CivGraphList.h" />
<ClInclude Include="CivHydDataType.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CivGraphFactory.cpp" />
<ClCompile Include="CivGraphList.cpp" />
<ClCompile Include="CivHydDataType.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
......
......@@ -18,10 +18,22 @@
<ClInclude Include="CivGraphList.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="CivHydDataType.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="CivGraphFactory.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CivGraphList.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="CivHydDataType.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="CivGraphFactory.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -278,6 +278,9 @@ bool CivPgConn::createTable(CivTableTemp& temp)
bool CivPgConn::open()
{
if (mIsOpen)
return true;
mConn = PQconnectdb(mUri);
if (PQstatus(mConn) == CONNECTION_BAD) {
mConn = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment