floyd算法思想:1,构建一个邻接矩阵存储任意两点之间的权值如图D0.
2、例如求v1,v4之间的最短路径。先增加v2做中间顶点,D[1][4]=∞。if(D[1][4]>D[1][2]+D[2]4])=6+4)D[1][4]=10;这样就可以了。
3、如不能在离得较远的两点(例v1,v9)直接得到上述可以满足if的中间点,则跟据你书本的代码可以先构建原点到中间点的最短路径,继而就可以求得vi,v9之间的最短路径
假设这个图的weight matrix存在map[5][5]中,
for (int k=0; k<5; k++)处理完之后map[i][j]存的就是i,j之间的最短路径长度。
简单的说,当执行完一次最外层循环时,map记录的时i,j之间允许使用中间节点{0, ..., k}的最短路径。
更多扩展补充
扩展
还是不明白啊
补充
最开始的时候,map中的值是两点间的直接距离,可以看作是不使用中间节点的最短路径长度。最外层循环执行过一次以后,map中记录的就是允许使用节点0做中间节点的最短路径长度。到这里都可以理解吧?
那么假设map目前存的是允许使用节点0...k-1 的情况下,节点之间的最短路径。那么在允许使用节点0...k的情况下i,j之间的最短路径就是min{map[i][j], map[i][k]+map[k][j]}
还有哪里不明白,请指明
扩展
我那题目应该不是叫我写代码的吧 , 我想要那个答案
补充
依然用矩阵表示两点之间的最短路径:
0 9 2 5 7
10 0 12 3 5
10 7 0 3 5
7 4 9 0 2
5 14 7 10 0
floyd算法用以解决所有点对最短路径。
floyd算法基本思想是递推,动态规划。我们记 dp[j][k] 表示图中顶点 i 到 j 的最短路径,且该最短路径中,所经过的中间顶点(不包括 i, j) 的范围为 [1,k],由此我们可以得到以下递推式:
dp[j][k]= w[j] 如果 k== 0
dp[j][k]= min{ dp[k][k-1]+ dp[k][j][k-1] } 如果 k>= 1。
实际中,空间上我们可以减少一维。
floyd算法同样可以来解决一些其它问题
1) 有向图的最小(或最大)环
这个问题答案其实就是自身到自身的最短路径,运行完 floyd 后,对每个顶点取自身到自身距离的最小者。
2) 无向图的最小环
根据以上的递推式,dp[j][k] 表示 i 到 j 的最短路径,且该最短路径中,所经过的中间顶点(不包括 i, j) 的范围为 [1,k]。
此时我们可以枚举出顶点序列最大为 k+ 1 的所有最小环,如何枚举:设与顶点序列最大的顶点 k+ 1 相连的两个顶点为 x, y,x,y 须满足 x, y<= k。这样最小环构成为 边
Poj 1734 Sightseeing trip
#include
#include
int const N= 110, inf= 5000000;
int mat[N][N], dist[N][N], pre[N][N], path[N], n, m, top= 0, p;
#define min(a,b) ((a)<(b)?(a):(b))
int main(){
scanf("%d%d",&n,&m );
for( int i= 0; i<= n; ++i )
for( int j= 0; j<= n; ++j ){
mat[j]= inf; dist[j]= inf; pre[j]= j; }
while( m-- ){
int u, v, d;
scanf("%d%d%d",&u,&v,&d);
mat[v]= min( mat[v], d );
mat[v]= mat[v];
dist[v]= mat[v]; dist[v]= mat[v];
}
int ans= inf;
for( int k= 1; k<= n; ++k ){
for( int x= 1; x< k; ++x )
for( int y= 1; y< x; ++y ){
if( mat[x][k]+ mat[k][y]+ dist[x][y]< ans ){
ans= mat[x][k]+ mat[k][y]+ dist[x][y];
top= 0; path[top++]= k; p= x;
while( p!= y ){
path[top++]= p; p= pre[p][y];
}
path[top++]= y;
}
}
for( int i= 1; i<= n; ++i )
for( int j= 1; j<= n; ++j )
if( dist[k]+ dist[k][j]< dist[j] ){
dist[j]= dist[k]+ dist[k][j];
pre[j]= pre[k]; }
}
if( top>0 ){
printf("%d", path[0] );
for( int i= 1; i< top; ++i ) printf(" %d", path );
puts("");
}else puts("No solution.");
return 0;
}
A矩阵是邻接矩阵,对角线上为o,其余位置数字表示的是两点之间距离,比如A(1,2)=2,表示从第一个点到第二个点的距离为2.inf是无穷大的意思,这里表示没有直接沟通这两点的路。
n=length(D);设定n为D矩阵的长度。
接下来的两重循环,得到的R矩阵是n*n的矩阵,它每个数据表示的是路径,比如:R(1,3)=1;表示路径为:1-1-3.这里是初始化路径了。
后面的三重循环是floyd算法的关键所在,就是更新路线了。里面的那个判断指的是:
假设有3个点,1 2 3;如果我从1-2-3之间总距离小于1-3的距离,那么我R(1,3)=2;这就是选取更近的路线了。
最后的两个判断是为了不让曾经走过的点再次被遍历。就是不回头的意思了,这个一般都可以忽略了,你照打上去就是了。
不知道这样的解释你是否满意。
更多扩展补充
扩展
额,矩阵R保存的是路线么?怎么看。。。
补充
是的 你在历史窗口看啊 你matlab界面不清楚么?
扩展
我的意思是R矩阵的结果出来了怎么看它表示的最短路径是哪一条?
R:
补充
比如我选择从1到8的最短距离,那么首先看到的是第1行第8列,是5,然后是第一行第5列,是2,然后是1行2列是1,所以最短路径是1258
分n 个阶段,用邻接矩阵求关联和权值时间O(1),每个阶段需要对n^2个元素对比较
因此时间复杂度为O(n^3)
至于求路径,参加其原文,又多了一个循环,效率不高,最好是用路径矩阵,这样求路径的时间复杂度也是O(n^3)
心理能量即心理力量,是促使人意识到自己的需求和主体性、驱使人采取适当行为的冲动、勇气、意志力及各种特征的情绪、感情等心理力量。
我在另一本书中说过:“心理能量不能象测量物质能量一样,用物理学的方法测量。因而一些心理学家在物理学家的面前很有自卑感,他们觉得象电能、动能、光能等等能量形式是“客观存在”的,而心理能量则只是一个假设性的概念,是不是真存在很难说。在这些心理学家的心目中,除非有一天,科学家测量出心理能量是身体里的一种生物电能量或者化学能量,否则就不能说心理能量存在。心理学家在物理学家面前的这种自卑由来已久,行为主义心理学不就是在竭力模仿物理学,在寻求物理学一样的客观性吗。但是这自卑本来是大可以不必的,因为随着现代物理学的发展,机械的唯物主义的观点越来越式微。现代的物理学家发现,物理学中的“能量”也不过是一个概念而已,也不过是为了说明一些物质运动的现象而假设的存在而已。本来它和心理学中的“心理能量”概念就没有什么差别,都是为了解释现象提出的概念。”
按照本书的理论体系,实际上我们可以更清楚地说:心理能量不是客观现实,而是一个“心理现实”,也就是说是对某种心理经验进行符号化的产物。作为心理能量这个概念的基础,是我们经验中的一种大致可以说成“有生命力”、“有活力”的体验。心理动力学的治疗实践中,心理治疗师也都可以清楚地感受到来访者给我们的一种感受,在他们顺利的时候,这种生命力表现为的激情和欢乐;在逆境中,则体现为一种顽强的精神,一种想要有生命活力的意愿。
这些体验归根结底是对生命意志,或者一种生命本能的体验。而当我们把被体验到的事物称为“心理能量”时,实际上我们已经在进行符号化了,也就是说我们在用“能量”的概念去把这种体验或者说心理经验变成了心理现实。
意象对话理论在这里和心理动力学一致,同意心理能量来表征人对生命意志或生的本能的经验。
二、心理能量的产生
心理能量的产生,有二种形式。一种是在适当的心理状态下,心理能量自发产生。另一种是在激发了某种本能时,会激发以这种本能有关形式的心理能量。
在用想象的方式,也就是用意象去反映心理能量的时候,心理能量经常可以被想象为两个意象之一:水或者火。
心理能量或说生命力的源泉,在哲学的角度上看,我认为归根结底是宇宙中生生不息的一种能量,也就是赫拉克里特所说的“宇宙是永恒的活火”。作为人的最高境界,就是和宇宙中的这“活火”沟通,从而在自发的情况下,从这活火中得到无穷无尽的力量;或者说,是如同泉源中泉水源源不断地流出来。在心理经验上,这时的心理能量会被体验为一种光明澄澈、一种极限的欢乐、一种没有内容的空又是无限的创造力,有如太阳的光明源源不绝,有如浩瀚银河旋转不息。还有就是在我们并没有欲求、期望、思虑,只是在单纯地融入生命,体会生命的那些时刻,比如在很美的森林中或者海边,而我们又没有任何干扰性的思想时,这时候也会有自发产生的能量,让人有生机勃勃,浑身有劲的感觉。
这样产生的心理能量,是流动的,没有或极少受阻碍,也没有和某种特定的本能结合,也没有和某种具体的情绪结合,表现出的是比情绪更原初的状态。实际上,这就是我们对自己的生命意志的直接经验以及表达。
另一种心理能量产生的方式是本能力量被激发。
当一个情境需要心理能量的时候,由于本能的存在,在本能中激发出了心理能量。这些心理能量根据本能不同有不同的形式,例如当我们被一个异性吸引的时候,在性的本能中激发了我们的性本能能量。于是我们变得活跃、变得不知疲倦、激情澎湃、或者妙语连珠、我们焕发出了光彩、我们快乐。当我们进行竞赛的时候,我们的竞争本能被激发。于是我们兴奋、激动、紧张,而且变得跃跃欲试,我们会从事竞赛而且获得快乐。心理能量最常见的基本形式就是性的能量和进取的能量。
心理能量激发后,由潜在的能量变为现实的能量,就有了基本的形式。被激发的心理能量,可以表现为多种形态,比如表现为一种兴奋、激动、唤起,一种内驱力或动机,很重要的一种形态是表现为情绪。心理能量表现于情绪时,情绪的量就是这个心理能量大小的表征。
这本我、自我和超我本是弗洛伊德对于人格结构进行分析时所提出的概念,在《自我与本我》一书中对人格的结构有详尽的介绍。
本我(id)包含要求得到眼前满足的一切本能的驱动力,就像一口沸腾着本能和欲望的大锅。它按照快乐原则行事,急切地寻找发泄口,一味追求满足。本我中的一切,永远都是无意识的。
自我(ego)处于本我和超我之间,代表理性和机智,具有防卫和中介职能,它按照现实原则来行事,充当仲裁者,监督本我的动静,给予适当满足。自我的心理能量大部分消耗在对本我的控制和压制上。任何能成为意识的东西都在自我之中,但在自我中也许还有仍处于无意识状态的东西。
对于本我和自我的关系,弗洛伊德有这样一个比喻:本我是马,自我是马车夫。马是驱动力,马车夫给马指方向。自我要驾御本我,但马可能不听话,二者就会僵持不下,直到一方屈服。对此弗洛伊德有一句名言:“本我过去在哪里,自我即应在哪里。”自我又像一个受气包,处在“三个暴君”的夹缝里:外部世界、超我和本我,努力调节三者之间相互冲突的要求。
超我(superego)代表良心、社会准则和自我理想,是人格的高层领导,它按照至善原则行事,指导自我,限制本我,就像一位严厉正经的大家长。弗洛伊德认为,只有三个“我”和睦相处,保持平衡,人才会健康发展;而三者吵架的时候,人有时会怀疑“这一个我是不是我”?或者内心有不同的声音在对话:“做得?做不得?”或者内心因为欲望和道德的冲突而痛苦不堪?或者为自己某个突出其来的丑恶念头而惶恐?这种状况如果持续得久了,或者冲突得比较严重,就会导致神经症的产生。
这个是M文件中的函数啊,只有运行在主界面并且这样运行:
floyd(a)(把a输入括号这里才行)
单独运行当然没有定义a啊
%floyd.m
%采用floyd算法计算图a中每对顶点最短路
%d是矩离矩阵
%r是路由矩阵
function [d,r]=floyd(a)
n=size(a,1);
d=a;
for i=1:n
for j=1:n
r(i,j)=j;%原始默认路径都是各节点间直接到达的距离
end
end
r
for k=1:n
for i=1:n
for j=1:n
if d(i,k)+d(k,j) d(i,j)=d(i,k)+d(k,j);%这里是不是输入错了?看不懂中间为甚么有个空格;
但总体意思是说如果从i节点先到k节点再到j节点间距离比从i直接到j要近的话就替换掉原先那条路径
r(i,j)=r(i,k)
end
end
end
k
d
r
end