求最短路径算法。

wwmwenzhu 2008-12-30 09:07:59
数组N*N,求点A到点B的路径
我用搜索回溯算法和扩散实现(标出所有与A相通的点)分别实现的,但不是最短路径
现求一个更好的算法,最好是最短路经。
要求代码实现!!
...全文
517 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
wei121422198 2011-07-12
  • 打赏
  • 举报
回复
#include<iostream>
using namespace std;
int main()
{
int a[103][103],i,j,s[103],d[103],n,t,k,m,x,y;
while(scanf("%d%d",&n,&m),n+m)
{
memset(a,0,sizeof(a));
for(i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&t);
// if(((a[x][y]!=0&&a[x][y]<t)||a[x][y]==0)&&t>=1)
a[x][y]=t;a[y][x]=t;
}
memset(s,0,sizeof(s));
s[1]=1; //起点为1
for(j=1;j<=n;j++)
d[j]=a[1][j];
for(i=1;i<n;i++)
{
t=9999999;
for(j=2;j<=n;j++)
if(!s[j]&&d[j]<t&&d[j]!=0) {t=d[j];k=j;}
s[k]=1;
for(j=2;j<=n;j++)
if(!s[j]&&(d[j]>d[k]+a[k][j]||d[j]==0)&&d[k]!=0&&a[k][j]!=0)
d[j]=d[k]+a[k][j];
}
cout<<d[n]<<endl;//起点为1到2,3,最短
}
return 0;
}
f_x_p0324 2011-06-30
  • 打赏
  • 举报
回复
动态规划的思想解决这类的问题
huangpeng8612 2008-12-30
  • 打赏
  • 举报
回复
工作之余告诉你了方法.还得花时间给你实现.还是楼主牛.从没见过这样请教问题的.也罢.留给有心人去看吧.这点时间还是省着挣点工时费吧.
xianyuxiaoqiang 2008-12-30
  • 打赏
  • 举报
回复
一上午写了个Dijkstra算法玩玩。
#include <iostream>
#include <string>
using namespace std;
#define MAX 0xFFFF
#define N 6

class Node
{
private:
string routine;
int value;
bool state;
public:
Node()
{
routine = "";
value = MAX;
state = false;
}
void set_val(int v)
{
value = v;
}
void set_rout(string rou)
{
routine = rou;
}
void setstate(bool b)
{
state = b;
}
int get_val()
{
return value;
}
string get_rout()
{
return routine;
}
bool getstate()
{
return state;
}
};

int print_result(Node & node, int);
int print_map(unsigned int [N][N]);
int Dijkstra(unsigned int [N][N], Node *);
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int map[N][N];
Node nodes[N];
for(int i = 0; i < N; ++i)
{
for(int j = 0; j < N; ++j)
{
if(i == j)
{
map[i][j] = 0;
}
else
{
map[i][j] = i * 3 - j + N;
}
}
}
for(int i = 0; i < N; ++i)
{
for(int j = 0; j < N; ++j)
{
if(i < j)
{
map[i][j] = map[j][i];
}
}
}
map[1][2] = map[2][1] = 1;
print_map(map);
Dijkstra(map, nodes);
for(int i = 1; i < 6; ++i)
{
print_result(nodes[i], i);
}

return 0;
}
int print_map(unsigned int map [N][N] )
{
cout << "The map is like this :" << endl << " ";

for(int i = 0; i < N; ++i)
{
cout << (char)('A'+i) << " ";
}
cout << endl;
for(int i = 0; i < N; ++i)
{
cout << (char)('A' +i) << " ";
for(int j = 0; j < N; ++j)
{
if(map[i][j] < 10)
{
cout << map[i][j] << " ";
}
else
{
cout << map[i][j] << " ";
}
}
cout << endl;
}
return 0;
}
int print_result(Node & node, int nodeid)
{
if(nodeid < 1 || nodeid >= N)
{
cout << "Invalid node id" << endl;
return -1;
}
cout << "The shortest routine from A to " << (char)('A' + nodeid) << " is :" << endl;
cout << node.get_rout() << endl << "The value is : " << node.get_val() << endl;
return 0;
}
int Dijkstra(unsigned int map[N][N], Node *nodes)
{
unsigned int minid = 0;
unsigned int min = MAX;
unsigned int middleid = 0;
unsigned int temp = 0;
bool bridgemin = false;
bool flag = true;
for(int i = 1; i < N; ++i)
{
if(map[0][i] < min)
{
minid = i;
min = map[0][i];
}
}
nodes[minid].setstate(true);
nodes[minid].set_val(min);
string oldrout = nodes[minid].get_rout();
string a = "A -> ";
string b = " -> ";
if(oldrout.compare("") == 0)
{
nodes[minid].set_rout(oldrout + a + (char)('A' + minid));
}
else
{
nodes[minid].set_rout(oldrout + b + (char)('A' + minid));
}
while(flag)
{
bridgemin = false;
flag = false;
min = MAX;
for(int i = 1; i < N; ++i)
{
if(!nodes[i].getstate())
{
if(map[0][i] < min)
{
bridgemin = false;
flag = true;
minid = i;
min = map[0][i];
}
for(int j = 1; j < N; ++j)
{
if(nodes[j].getstate())
{
temp = nodes[j].get_val() + map[i][j];
if(temp < min)
{
flag = true;
minid = i;
middleid = j;
bridgemin = true;
min = temp;
}
}
}
}
}
if(flag)
{
nodes[minid].setstate(true);
nodes[minid].set_val(min);
oldrout = nodes[minid].get_rout();
if(!bridgemin)
{
if(oldrout.compare("") == 0)
{
nodes[minid].set_rout(a + (char)('A' + minid));
}
else
{
nodes[minid].set_rout(oldrout + b + (char)('A' + minid));
}
}
else
{
nodes[minid].set_rout(nodes[middleid].get_rout() + b + (char)('A' + minid));
}
}
}




return 0;
}
huangpeng8612 2008-12-30
  • 打赏
  • 举报
回复
其实书上应该有求最短距离的算法的.求最短路径的算法也有很多,但是实现往往比较复杂.通过最短距离求最短路径的话更容易理解,而且实现起来比较简单.我是在一次数学建模中被逼着想到的.不知道哪本书上有没有.
huangpeng8612 2008-12-30
  • 打赏
  • 举报
回复
但是有一点:上面的算法求得的最短距离是唯一的,但是最短路径不一定唯一,只求出了一个最短路径.如果要求所有的最短路径,则应该在第2步处理.对于每一个C[i][k]+P[k][j]=C[i][j]的k,都能作为最短路径中的最后一个节点.
huangpeng8612 2008-12-30
  • 打赏
  • 举报
回复
这已经是最快的方式了.目前好像没有比它更快的算法了.
liberpc 2008-12-30
  • 打赏
  • 举报
回复
算法资料有的
huangpeng8612 2008-12-30
  • 打赏
  • 举报
回复
用这个算法:任意两点最短路径.得到的是这两点之间最短路径的长度.然后再从后向前反过来,由最短路径的长度反求最短路径是什么.其实是一动态规划算法.思想如下:
1.假设数据是P,则首先求P[i]到P[j]的最短距离.其中0<=i,j<n,也即是求出任意两点之间的最短距离.求之前,这么分析:
P[i]到P[n-1]的最短路径只有两种情况:P[i]经过P[k]再到P[n-1]和P[i]不经过P[k]而到P[n-1].因此P[i]到P[n-1]的最短距离是:MAX{P[i][k]+P[k][n], P[i]不经过P[k]到达P[n-1]的最短距离}.所有的思想也就这么多.下面说怎么做.
记C[n][n]为P中任意两点之间的最短距离.即C[i][j]为P[i]到P[j]的最短距离.
初始时,令C[i][j]=P[i][j],其中0<=i,j<n.就是将P复制到C中.
然后:
for i=0 to n-1
for j=0 to n-1
for k=0 to n-1
C[i][j]=min{C[i][j], C[i][k]+C[k][j]}
end
end
end
这样就求得了任意两点间的最短距离.
2.从最短距离反求最短路径:
现在已经知道C[i][j]就是P[i]到P[j]的最短距离.然后从上面过程反思:C[i][j]是怎么来的?也就是在最终得到C[i][j]时最后一次是通过哪个点来的?也就是从P[i]到P[j]的最短路中P[j]前面的那个点是谁?
假设它是p[k]则肯定有:P[k][j]+C[i][k]=C[i][j].按照这个条件找到那个k,也就找到了从P[i]到P[j]的最短路径中最后一个点(如果P[j]不算的话).
找到它之后,再找从P[i]到P[k]的最短路径吧.直到找到一m,从P[i]到P[m]的最短路径是P[i]到P[i]的最短路径.也就是上面过程直到k=i为止.则把每一步求得的那个点连起来就是了.
就呆在云上 2008-12-30
  • 打赏
  • 举报
回复
如果是求连通图的已知两点间的最短距离,下面这个算法会有帮助:
BFS(G, s) {
initialize vertices;
Q = {s}; // Q is a queue (duh); initialize to s
while (Q not empty) {
u = RemoveTop(Q);
for each v  u->adj {
if (v->color == WHITE)
v->color = GREY;
v->d = u->d + 1;
v->p = u;
Enqueue(Q, v);
}
u->color = BLACK;
}
}
思路是:从你要的2个节点(from,to)中的一个开始广度优先一个图,就生成一个以from为root的生成树,从这棵数中依次向下访问就好了
MAlice 2008-12-30
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 xianyuxiaoqiang 的回复:]
有书还是看书吧。自己动手丰衣足食
[/Quote]
up
OenAuth.Net 2008-12-30
  • 打赏
  • 举报
回复
算法上面的都说了,不过要源代码,写起来比较痛苦
wwmwenzhu 2008-12-30
  • 打赏
  • 举报
回复
什么广度优先、深度优先、A*算法,Dijkstra 等等,
代码?
而且如何最短,实现最简单,不要理论的东西!!
就呆在云上 2008-12-30
  • 打赏
  • 举报
回复

Dijkstra
或者floyd算法
代码就麻烦了啊
xianyuxiaoqiang 2008-12-30
  • 打赏
  • 举报
回复
有书还是看书吧。自己动手丰衣足食
Wolf_FienD 2008-12-30
  • 打赏
  • 举报
回复
LZ的表达..........
星羽 2008-12-30
  • 打赏
  • 举报
回复
把问题描述清楚点,求最短路径,用bfs
oo 2008-12-30
  • 打赏
  • 举报
回复
广度优先搜索
oo 2008-12-30
  • 打赏
  • 举报
回复
干吗呢
wwmwenzhu 2008-12-30
  • 打赏
  • 举报
回复
网速太慢,发了三个,顺便散分吧!
随着通信电子技术的迅速发展,信息技术给家居行业产生了深远的影响,家居环境的智能化监控已经成为智能家居的一个重要的发展方向。人们逐渐对自己的生活提出一种更高的要,他们需要一种智能化、可交互,并且融合现代创新科技的产品来改善他们的生活环境,使他们生活更加安全、舒适、便捷、智能。本文根据智能家居的发展背景和研究现状,并且从实用性和可行性角度出发,研究设计了一种基于STM32单片机的智能家居系统。该系统由一个多功能综合的技术系统组成,各个多功能子系统间具有协同配合能力。基于STM32单片机实现的功能子系统包括:智能温度检测,智能湿度检测,智能烟雾/火灾检测智能检测,无线传输,人机交互机构,风扇调节,报警模块。 整个系统分为前端51单片机采集板和后端STM32单片机接收板。 采集板使用DHT11温湿度传感器、MQ烟雾传感器完成室内家居环境的采集。然后通过nRFL24L01将采集到的数据发送给后端。接收板使用LCD1602完成数据显示、使用蜂鸣器模块报警,使用风扇驱动模块调节室内家居环境。本文完成了智能家居控制系统前端、后端软硬件的设计,使用Altium designer绘制了电路原理图,使用Keil C完成了51单片机和STM32单片机的编程与调试。 最后,对本文设计的基于STM32的智能家居控制系统进行部署调试。试验结果表明,该系统可成功应用在智能家居环境检测调节和火灾安全防护的领域,可提高家居生活智能化水平。

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧