用C++创建一个图,并寻找最短路径

用C++创建一个图,并寻找最短路径,第1张

下面这个是我以前做的,你可以参考一下。

用VC++建一个工程,根据你的需要,修改邻接矩阵就可以了;源代码如下:

/燃悉/ Stack.h: interface for the Stack class.

//

//////////////////////////////////////////////////////////////////////

#if !defined(AFX_STACK_H__289E76B1_034C_4426_AE27_6ADCC13EDBCD__INCLUDED_)

#define AFX_STACK_H__289E76B1_034C_4426_AE27_6ADCC13EDBCD__INCLUDED_

#include<iostream.h>

#if _MSC_VER >1000

#pragma once

#endif // _MSC_VER >1000

#define MaxSize 1024

template <class Type>class Stack{//堆栈类

private:

Type data[MaxSize]

int top

public:

Stack(){//初始化栈

top = -1

}

virtual~Stack()

bool IsEmpty()//判断栈为空

bool IsFull() //判断栈为满

int GetTop() //取top的位置

void Push(Type)//进栈

Type Pop()//退栈

}

template <class Type>Stack<Type>::~Stack(){

}

template <class Type>bool Stack<Type>::IsEmpty(){

return(top == -1)

}

template <class Type>bool Stack<Type>::IsFull(){

return(top == MaxSize-1)

}

template <class Type>int Stack<Type>::GetTop(){

return top

}

template <class Type>void Stack<Type>::Push(Type item){

if(IsFull())

cout<<"栈满!\n"

else{

top++

data[top] = item

}

}

template <class Type>Type Stack<Type>::Pop(){

if(IsEmpty()){

cout<<"栈空!\n"

return NULL

}

else{

Type item

item = data[top]

top--

return item

}

}

#endif // !defined(AFX_STACK_H__289E76B1_034C_4426_AE27_6ADCC13EDBCD__INCLUDED_)

// AdjMatrix.h: interface for the AdjMatrix class.

//

//////////////////////////////////////////////////////////////////////

#if !defined(AFX_ADJMATRIX_H__220DF675_DDB5_4E64_BD89_CDDA2C1F7804__INCLUDED_)

#define AFX_ADJMATRIX_H__220DF675_DDB5_4E64_BD89_CDDA2C1F7804__INCLUDED_

#include <iostream.h>

#include <iomanip.h>

#include "Stack.h"

#define INT_MAX 0x7FFFFFFF

#if _MSC_VER >1000

#pragma once

#endif // _MSC_VER >历绝 1000

template <class Type>

void Make2DArray(Type ** &x,int rows,int cols){//创建二维数组x

x = new Type *[rows]//创建行指针

for(int i = 0i <rowsi++)//为每一行分配空间

x[i] = new Type[cols]

}

template <class Type>

void Delete2DArray(Type ** &x,int rows){//删除二维肢段姿数组x

for(int i = 0i <rowsi++)//释放为每一行所分配的空间

delete[]x[i]

delete[]x//删除行指针

x = NULL

}

class AdjMatrix{//方阵类

double **a//数据缓存区

public:

AdjMatrix(double **b = NULL,int dimention = 0){//初始化方阵

Make2DArray(a,dimention+1,dimention+1)

a[0][0] = dimention

for(int i = 1,j = 1i <= dimention,j <= dimentioni++,j++){

a[i][0] = 0

a[0][j] = 0

}

if(b)

for(int i1 = 1i1 <= dimentioni1++)

for(int j1 = 1j1 <= dimentionj1++)

a[i1][j1] = b[i1-1][j1-1]

}

virtual ~AdjMatrix()//析构函数

AdjMatrix &operator = (const AdjMatrix &)//重载赋值运算符=

void Trs(AdjMatrix &)//矩阵转置:B=trs(*this)

void Show()//显示结果

void ShortestPath_Floyed()//弗洛伊德算法,求每对顶点之间的最短路径

void ShortestPath_Dijkstra(int)//狄克斯特拉算法,求单源最短路径

//输入v为源点编号

}

#endif // !defined(AFX_ADJMATRIX_H__220DF675_DDB5_4E64_BD89_CDDA2C1F7804__INCLUDED_)

// AdjMatrix.cpp: implementation of the AdjMatrix class.

//

//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "AdjMatrix.h"

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

AdjMatrix::~AdjMatrix(){

int Dim = (int)a[0][0]+1

Delete2DArray(a,Dim)

}

AdjMatrix &AdjMatrix::operator = (const AdjMatrix &matrix){

int Dim1 = (int)a[0][0],Dim2 = (int)matrix.a[0][0]

Delete2DArray(a,Dim1+1)

Make2DArray(a,Dim2+1,Dim2+1)

for(int i = 0i <= Dim2i++)

for(int j = 0j <= Dim2j++)

a[i][j] = matrix.a[i][j]

return *this

}

void AdjMatrix::Trs(AdjMatrix &B){

int Dim1 = (int)a[0][0],Dim2 = (int)B.a[0][0]

Delete2DArray(B.a,Dim2+1)

Make2DArray(B.a,Dim1+1,Dim1+1)

B.a[0][0] = Dim1

for(int i = 1,j = 1i <= Dim1,j <= Dim1i++,j++){

B.a[i][0] = 0

B.a[0][j] = 0

}

for(int i1 = 1i1 <= Dim1i1++)

for(int j1 = 1j1 <= Dim1j1++)

B.a[i1][j1] = a[j1][i1]

}

void AdjMatrix::Show(){

if((int)a[0][0] == 0)

cerr<<"Error!矩阵不存在!\n"

else{

for(int i = 1i <= a[0][0]i++){

for(int j = 1j <= a[0][0]j++){

if(a[i][j] == INT_MAX)

cout<<setw(5)<<setprecision(7)<<"∞"<<'\t'

else

cout<<setw(5)<<setprecision(7)<<a[i][j]<<'\t'

}

cout<<endl

}

}

}

void AdjMatrix::ShortestPath_Floyed(){

int Dim = (int)a[0][0],pre

AdjMatrix A,Path

this->Trs(Path)

Path.Trs(A)//取A=*(this)

for(int i = 1i <= Dimi++){

for(int j = 1j <= Dimj++)

Path.a[i][j] = -1

}

for(int k = 1k <= Dimk++){

for(int i1 = 1i1 <= Dimi1++)

for(int j1 = 1j1 <= Dimj1++)

if(A.a[i1][j1] >A.a[i1][k]+A.a[k][j1]){

A.a[i1][j1] = A.a[i1][k]+A.a[k][j1]

Path.a[i1][j1] = k

}

}

cerr<<"↘Floyed算法求解如下:\n"

for(int i2 = 1i2 <=Dimi2++){//输出最短路径

for(int j2 = 1j2 <=Dimj2++)

if(i2 != j2){

cout<<" "<<i2<<"->"<<j2<<": "

if(A.a[i2][j2] == INT_MAX){

if(i2 != j2)

cout<<"不存在路径!\n"

}

else{

cout<<"路径长度:"<<setw(3)<<A.a[i2][j2]<<" "

cout<<"路径:"<<i2<<"->"

pre = (int)Path.a[i2][j2]

while(pre != -1){

cout<<pre<<"->"

pre = (int)Path.a[pre][j2]

}

cout<<j2<<endl

}

}

}

}

void AdjMatrix::ShortestPath_Dijkstra(int v){

int Dim = (int)a[0][0]

AdjMatrix A,temp

this->Trs(temp)

temp.Trs(A)//取A=*(this)

int *s, *path,u,pre

s = new int[Dim+1],path = new int[Dim+1]

s[0]=0,path[0]=0

double *dist,mindis

dist = new double[Dim+1]

dist[0] = 0.0

for(int k = 1k <= Dimk++){

dist[k] = A.a[v][k]//距离初始化

s[k] = 0//s[]置空

if(A.a[v][k] <INT_MAX)//路径初始化

path[k] = v

else

path[k] = -1

}

s[v] = 1,path[v] = 0//源点编号v放入s中

for(int i = 1i <= Dimi++){//循环直到所有顶点的最短路径都求出

mindis = INT_MAX

u = -1

for(int j = 1j <= Dimj++){//选取不在s中且具有最小距离的顶点u

if(s[j] == 0 &&dist[j] <mindis){

u = j

mindis = dist[j]

}

}

if(u != -1){

s[u] = 1

for(int r = 1r <= Dimr++)

if(s[r] == 0)

if(A.a[u][r] <INT_MAX &&dist[u]+A.a[u][r] <dist[r]){

dist[r] = dist[u]+A.a[u][r]

path[r] = u

}

}

}

cout<<"↘Dijkstra算法求解如下:\n"

Stack<int>st

for(int i1 = 1i1 <= Dimi1++){//输出最短路径的长度,路径逆序输出

if(i1 != v){

cout<<" "<<v<<"->"<<i1<<": "

if(s[i1] == 1){

cout<<"路径长度:"<<setw(3)<<dist[i1]<<" "

pre = i1

cout<<"路径:"

while(pre != v){//一直回溯到初始顶点

st.Push(pre)

pre = path[pre]

}

st.Push(pre)

while(0 <st.GetTop() ){

cout<<st.Pop()<<"->"

}

cout<<st.Pop()<<endl

}

else

cout<<"不存在路径!\n"

}

}

}

// LinkGraph.h: interface for the LinkGraph class.

//

//////////////////////////////////////////////////////////////////////

#if !defined(AFX_LINKGRAPH_H__711D918A_0412_49B6_A496_B78EAAB3C611__INCLUDED_)

#define AFX_LINKGRAPH_H__711D918A_0412_49B6_A496_B78EAAB3C611__INCLUDED_

#include <iostream.h>

#include <iomanip.h>

#include <string.h>

#include "Stack.h"

#define INT_MAX 0x7FFFFFFF

#if _MSC_VER >1000

#pragma once

#endif // _MSC_VER >1000

struct EdgeNode{ //每一个顶点建立的单链表中结点的类型

int index//邻接点序号

double value //边的权值

EdgeNode *next//下一条边的顶点

EdgeNode(EdgeNode *ne = NULL):next(ne){}//可选择参数的默认构造函数

}

struct VertexNode{ //单链表中头结点类型

char name[32]//结点信息

int indegree //入度计数域

EdgeNode *link//指向第一条边结点

VertexNode(EdgeNode *li = NULL):link(li){}//可选择参数的默认构造函数

}

class LinkGraph{//图的邻接表类

private:

int num//实际顶点数

VertexNode *adjlist//单链表头结点数组

public:

LinkGraph(char **names = NULL,double **matrix = NULL,int n = 0){

num = n

if(names){

EdgeNode *p1,*p2

int *temp

temp = new int[num]

for(int k = 0k <numk++)

temp[k] = 0

adjlist = new VertexNode[num]

for(int i = 0i <numi++){

strcpy(adjlist[i].name,*(names+i))

for(int j = 0j <numj++){

if(matrix[j][i] != 0)

temp[i]++

if(matrix[i][j] != 0){

adjlist[i].indegree++

p1 = new EdgeNode

p1->index = j

p1->value = matrix[i][j]

if(!adjlist[i].link){

adjlist[i].link = p1

p2 = p1

}

else{

p2->next = p1

p2 = p1

}

}

}

adjlist[i].indegree = temp[i]

}

}

else

adjlist = NULL

}

virtual ~LinkGraph()

void Show()

void TopologicalSort()

}

#endif // !defined(AFX_LINKGRAPH_H__711D918A_0412_49B6_A496_B78EAAB3C611__INCLUDED_)

// LinkGraph.cpp: implementation of the LinkGraph class.

//

//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "LinkGraph.h"

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

LinkGraph::~LinkGraph(){

EdgeNode *p1,*p2

if(adjlist){

for(int i = 0i <numi++){

p1 = adjlist[i].link

while(p1){

p2 = p1->next

delete p1

p1 = p2

}

}

}

delete []adjlist

}

void LinkGraph::Show(){

EdgeNode *temp

if(adjlist){

for(int i = 0i <numi++){

if(adjlist[i].link)

cout<<" "<<adjlist[i].name<<":: "

else

cout<<" "<<adjlist[i].name<<""

temp = adjlist[i].link

while(temp){

cout<<adjlist[temp->index].name<<" "

temp = temp->next

}

cout<<endl

}

}

}

void LinkGraph::TopologicalSort(){

Stack<int>st

EdgeNode *temp

int j,k,tag = 0

for(int i = 0i <numi++){

if(adjlist[i].indegree == 0)

st.Push(i)

}

cout<<"↘拓扑排序算法求解如下:\n"

while(!st.IsEmpty()){

j = st.Pop()

if(tag%6 == 0)

cout<<"\n "

tag ++

if(tag != num)

cout<<adjlist[j].name<<" ->"

else

cout<<adjlist[j].name<<endl

temp = adjlist[j].link

while(temp){

k = temp->index

adjlist[k].indegree --

temp = temp->next

if(adjlist[k].indegree == 0)

st.Push(k)

}

}

if(num == tag)

cout<<"\n 拓扑排序成功!\n"

else

cout<<"\n 失败,有向图中存在环!\n"

}

// Exercise_4.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include <iostream.h>

#include "AdjMatrix.h"

#include "LinkGraph.h"

#define MAXSIZE1 6

#define MAXSIZE2 11

void DisplayMenu()

int main(int argc, char* argv[]){

DisplayMenu()

double a[MAXSIZE1][MAXSIZE1] = { 0, 50, 10,INT_MAX,INT_MAX,INT_MAX,

INT_MAX, 0, 15, 50, 10,INT_MAX,

20, 70, 0, 15,INT_MAX,INT_MAX,

INT_MAX, 20,INT_MAX, 0, 35,INT_MAX,

INT_MAX,INT_MAX,INT_MAX, 30, 0,INT_MAX,

INT_MAX,INT_MAX,INT_MAX, 3,INT_MAX, 0}

char str[MAXSIZE2][32] = {"程序设计","数值分析","普通物理","高等数学","数据结构",

"人工智能","编译原理"," *** 作系统","计算机原理","线性代数","离散数学"}

double b[MAXSIZE2][MAXSIZE2] = {0,1,0,0,1,0,1,0,0,0,1,

0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,1,0,0,

0,1,1,0,0,0,0,0,0,1,0,

0,0,0,0,0,1,1,1,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,1,0,0,0,

0,1,0,0,0,0,0,0,0,0,0,

0,0,0,0,1,0,0,0,0,0,0}

double **matrix1

Make2DArray(matrix1,MAXSIZE1,MAXSIZE1)

for(int i1 = 0i1 <MAXSIZE1i1++){

for(int j1 = 0j1 <MAXSIZE1j1++)

matrix1[i1][j1] = a[i1][j1]

}

AdjMatrix A(matrix1,MAXSIZE1)

cout<<"↘邻接矩阵:\n"

A.Show()

cout<<"*******************************************************************************\n"

A.ShortestPath_Floyed()

cout<<endl

A.ShortestPath_Dijkstra(2)

char **names

Make2DArray(names,MAXSIZE2,12)

for(int s = 0s <MAXSIZE2s++){

strcpy(*(names+s),*(str+s))

}

double **matrix2

Make2DArray(matrix2,MAXSIZE2,MAXSIZE2)

for(int i2 = 0i2 <MAXSIZE2i2++){

for(int j2 = 0j2 <MAXSIZE2j2++)

matrix2[i2][j2] = b[i2][j2]

}

LinkGraph Graph(names,matrix2,MAXSIZE2)

cout<<"*******************************************************************************\n"

cout<<"↘邻接表:\n"

Graph.Show()

cout<<endl

Graph.TopologicalSort()

return 0

}

void DisplayMenu(){

char *menu[]={

" ☆☆ 图 ☆☆",

" 1. Floyed算法 2. Dijkstra算法 3. 拓扑排序算法 ",

NULL

}

for(int i=0menu[i]i++)

cout<<menu[i]<<'\n'

}

一、调用Matlab引擎

调用Matlab引擎可以在WIN32、MFC中使用,它的原理实际上相当于打开一个精简版的Matlab然后往橡册里面输命令。下面是调梁并宏用Matlab中的加法程序add.m的例子。

先在Matlab的work目录下创建add.m文件并编写程序如下:

function s = add (a, b) s = a+b在C程序中,首先打开精简版的Matlab

Engine *ep = engOpen (NULL)

编译运行后,会自动打开一个命令行监控窗口,输入pwd就可以看到当前的工作目录,于是需要先将工作目录转换至存放add.m的目录: engEvalString (ep, ”cd ..\\..\\work”)

engEvalString是往Matlab里输命令的函数,显然我们的目标是成功运行: engEvalString (ep, ”s=add(a,b)”)

目前Matlab中并没有a和b两个变量,因此需要在C中初始化这两个变量并转换成Matlab基本变量类型蔽模mxArray,才能将它们输入到Matlab中。

有两种情况。

首先,过A、B两告侍点做一条直线。

第一种情况:如果直线与河岸垂直a,那么,其交点C就是最近的打水点。

第二种情况:如果直线不与河岸垂直,则过河岸做A点的对称点袜梁吵D,然后连接BD与河岸交于E点,E点就渣配是最近的打水点,小明的打水路线其实是一条直线,两点之间直线最短大家都知道的.

抱歉,我这里没有画图工具,大家可以自己画一下.


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12313020.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存