布莱克·莱弗利 (Blake Lively) 穿斯特拉·麦卡特尼(Stella McCartney)超长镶铆钉靴裤出席《Gossip Girl》造型师Eric Daman新书发布派对
布莱克·莱弗利 (Blake Lively) 穿斯特拉·麦卡特尼(Stella McCartney)超长镶铆钉靴裤出席《Gossip Girl》造型师Eric Daman新书发布派对
支持键盘“←
点击下面图片,查看相关精彩图集
海报时尚网所有产品(包括图形设计、配色、页面展示形式等)、独家稿件文字及图片、社区文字及图片,均已受版权和产权保护。
任何公司及个人不得以任何方式复制,违者将依法追究责任,特此声明。迪杰斯特拉算法 -
定义及问题描述
定义 Dijkstra()算法是典型的算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表的方式,这里均采用永久和临时标号的方式。注意该算法要求图中不存在负权边。问题描述 在 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径。()
迪杰斯特拉算法 -
迪杰斯特拉算法
(Dijkstra)算法思想
按递增次序产生最短路径算法:
把V分成两组:
(1)S:已求出最短路径的顶点的集合
(2)V-S=T:尚未确定最短路径的顶点集合
将T中顶点按最短路径递增的次序加入到S中,
保证:(1)从源点V0到S中各顶点的最短路径长度都不大于
从V0到T中任何顶点的最短路径长度
(2)每个顶点对应一个距离值
S中顶点:从V0到此顶点的最短路径长度
T中顶点:从V0到此顶点的只包括S中顶点作中间
顶点的最短路径长度
依据:可以证明V0到T中顶点Vk的最短路径,或是从V0到Vk的
直接路径的权值;或是从V0经S中顶点到Vk的路径权值之和
(反证法可证)
求最短路径步骤
算法步骤如下:
1. 初使时令 S={V0},T={其余顶点},T中顶点对应的距离值
若存在&V0,Vi&,d(V0,Vi)为&V0,Vi&弧上的权值
若不存在&V0,Vi&,d(V0,Vi)为∝
2. 从T中选取一个其距离值为最小的顶点W且不在S中,加入S
3. 对T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的
距离值比不加W的路径要短,则修改此距离值
重复上述步骤2、3,直到S中包含所有顶点,即S=T为止
迪杰斯特拉算法 -
迪杰斯特拉算法的原理
首先,引进一个辅助向量D,它的每个分量D表示当前所找到的从始点v到每个终点vi的最短路径的长度。如D[3]=2表示从始点v到终点3的路径相对最小长度为2。这里强调相对就是说在算法过程中D的值是在不断逼近最终结果但在过程中不一定就等于最短路径长度。它的初始状态为:若从v到vi有弧,则D为弧上的权值;否则置D为∞。显然,长度为 D[j]=Min{D | vi∈V} 的路径就是从v出发的长度最短的一条最短路径。此路径为(v,vj)。 那么,下一条长度次短的最短路径是哪一条呢?假设该次短路径的终点是vk,则可想而知,这条路径或者是(v,vk),或者是(v,vj,vk)。它的长度或者是从v到vk的弧上的权值,或者是D[j]和从vj到vk的弧上的权值之和。 一般情况下,假设S为已求得最短路径的终点的集合,则可证明:下一条最短路径(设其终点为X)或者是弧(v,x),或者是中间只经过S中的顶点而最后到达顶点X的路径。因此,下一条长度次短的最短路径的长度必是D[j]=Min{D | vi∈V-S} 其中,D或者是弧(v,vi)上的权值,或者是D[k](vk∈S)和弧(vk,vi)上的权值之和。 迪杰斯特拉算法描述如下: 1)arcs表示弧上的权值。若不存在,则置arcs为∞(在本程序中为MAXCOST)。S为已找到从v出发的最短路径的终点的集合,初始状态为空集。那么,从v出发到图上其余各顶点vi可能达到的最短路径长度的初值为D=arcs[Locate Vex(G,v),i] vi∈V 2)选择vj,使得D[j]=Min{D | vi∈V-S} 3)修改从v出发到集合V-S上任一顶点vk可达的最短路径长度。
迪杰斯特拉算法 -
迪杰斯特拉算法C#程序
public class Edge
public string StartNodeID ;
public string EndNodeID ;
public double W //权值,代价
} 节点则抽象成Node类,一个节点上挂着以此节点作为起点的“出边”表。
public class Node
private string iD ;
private
edgeL//Edge的集合--出边表
public Node(string id )
this.iD =
this.edgeList = new ArrayList() ;
property#region property
public string ID
return this.iD ;
public ArrayList EdgeList
return this.edgeL
#endregion
在计算的过程中,我们需要记录到达每一个节点权值最小的路径,这个抽象可以用PassedPath类来表示:
/// &summary&
/// PassedPath 用于缓存计算过程中的到达某个节点的权值最小的路径
/// &/summary&
public class PassedPath
private string curNodeID ;
private bool beP //是否已被处理
pr //累积的权值
private ArrayList passedIDL //路径
public PassedPath(string ID)
this.curNodeID = ID ;
this.weight = double.MaxV
this.passedIDList = new ArrayList() ;
this.beProcessed =
#region property
public bool BeProcessed
return this.beP
this.beProcessed =
public string CurNodeID
return this.curNodeID ;
public double Weight
return this.
this.weight =
public ArrayList PassedIDList
return this.passedIDL
#endregion
另外,还需要一个表PlanCourse来记录规划的中间结果,即它管理了每一个节点的PassedPath。
/// &summary&
/// PlanCourse 缓存从源节点到其它任一节点的最小权值路径=》
/// &/summary&
public class PlanCourse
private Hashtable htPassedP
#region ctor
public PlanCourse(ArrayList nodeList ,string originID)
this.htPassedPath = new Hashtable() ;
Node originNode =
foreach(Node node in nodeList)
if(node.ID == originID)
originNode =
PassedPath pPath = new PassedPath(node.ID) ;
this.htPassedPath.Add(node.ID ,pPath) ;
if(originNode == null)
throw new Exception(&The origin node is not exist !&) ;
this.InitializeWeight(originNode) ;
private void InitializeWeight(Node originNode)
if((originNode.EdgeList == null) ||(originNode.EdgeList.Count == 0))
foreach(Edge edge in originNode.EdgeList)
PassedPath pPath = this[edge.EndNodeID] ;
if(pPath == null)
pPath.PassedIDList.Add(originNode.ID) ;
pPath.Weight = edge.W
#endregion
public PassedPath this[string nodeID]
return (PassedPath)this.htPassedPath[nodeID] ;
在所有的基础构建好后,路径规划算法就很容易实施了,该算法主要步骤如下:
(1)用一张表(PlanCourse)记录源点到任何其它一节点的最小权值,初始化这张表时,如果源点能直通某节点,则权值设为对应的边的权,否则设为double.MaxValue。
(2)选取没有被处理并且当前累积权值最小的节点TargetNode,用其边的可达性来更新到达其它节点的路径和权值(如果其它节点 经此节点后权值变小则更新,否则不更新),然后标记TargetNode为已处理。
(3)重复(2),直至所有的可达节点都被处理一遍。
(4)从PlanCourse表中获取目的点的PassedPath,即为结果。
下面就来看上述步骤的实现,该实现被封装在RoutePlanner类中:
/// &summary&
/// RoutePlanner 提供图算法中常用的路径规划功能。
/// &/summary&
public class RoutePlanner
public RoutePlanner()
#region Paln
//获取权值最小的路径
public RoutePlanResult Paln(ArrayList nodeList ,string originID ,string destID)
PlanCourse planCourse = new PlanCourse(nodeList ,originID) ;
Node curNode = this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;
#region 计算过程
while(curNode != null)
PassedPath curPath = planCourse[curNode.ID] ;
foreach(Edge edge in curNode.EdgeList)
PassedPath targetPath = planCourse[edge.EndNodeID] ;
double tempWeight = curPath.Weight + edge.W
if(tempWeight & targetPath.Weight)
targetPath.Weight = tempW
targetPath.PassedIDList.Clear() ;
for(int i=0 ;i&curPath.PassedIDList.Ci++)
targetPath.PassedIDList.Add(curPath.PassedIDList.ToString()) ;
targetPath.PassedIDList.Add(curNode.ID) ;
//标志为已处理
planCourse[curNode.ID].BeProcessed =
//获取下一个未处理节点
curNode = this.GetMinWeightRudeNode(planCourse ,nodeList ,originID) ;
#endregion
//表示规划结束
return this.GetResult(planCourse ,destID) ;
#endregion
#region private method
#region GetResult
//从PlanCourse表中取出目标节点的PassedPath,这个PassedPath即是规划结果
private RoutePlanResult GetResult(PlanCourse planCourse ,string destID)
PassedPath pPath = planCourse[destID] ;
if(pPath.Weight == int.MaxValue)
RoutePlanResult result1 = new RoutePlanResult(null ,int.MaxValue) ;
return result1 ;
string[] passedNodeIDs = new string[pPath.PassedIDList.Count] ;
for(int i=0 ;i&passedNodeIDs.Li++)
passedNodeIDs = pPath.PassedIDList.ToString() ;
RoutePlanResult result = new RoutePlanResult(passedNodeIDs ,pPath.Weight) ;
#endregion
#region GetMinWeightRudeNode
//从PlanCourse取出一个当前累积权值最小,并且没有被处理过的节点
private Node GetMinWeightRudeNode(PlanCourse planCourse ,ArrayList nodeList ,string originID)
double weight = double.MaxV
Node destNode =
foreach(Node node in nodeList)
if(node.ID == originID)
PassedPath pPath = planCourse[node.ID] ;
if(pPath.BeProcessed)
if(pPath.Weight & weight)
weight = pPath.W
destNode =
return destN
#endregion
#endregion
迪杰斯特拉算法 -
迪杰斯特拉算法pascal程序
type bool=array[1..10]
arr=array[0..10]
var a:array[1..10,1..10] //存储图的邻接数组,无边为10000
c,d,e: //c为最短路径数值,d为各点前趋,
t: //e:路径,t为辅助数组
i,j,n,m:
inf,outf:
////////////////////////////////////////////////////////////////////////////////
//不同题目邻接数组建立方式不一样
assign(inf,'dijkstra.in'); assign(outf,'dijkstra.out');
reset(inf); rewrite(outf);
read(inf,n);
for i:=1 to n do
for j:=1 to n do
read(inf,a[i,j]);
if a[i,j]=0 then a[i,j]:=10000;
////////////////////////////////////////////////////////////////////////////////
procedure dijkstra(qi: t: var c{,d}:arr); //qi起点,{}中为求路径部
var i,j,k,min: //分,不需求路径时可以不要
begin //t数组一般在调用前初始
t[qi]:= //化成false,也可将部分点
{for i:=1 to n do d[i]:= d[qi]:=0; } //初始化成true以回避这些点
for i:=1 to n do c[i]:=a[qi,i];
for i:=1 to n-1 do
min:=10001;
for j:=1 to n do
if (c[j]&min)and(not(t[j])) then begin k:=j; min:=c[j];
t[k]:=
for j:=1 to n do
if (c[k]+a[k,j]&c[j])and(not(t[j])) then
c[j]:=c[k]+a[k,j]; {d[j]:=k;}
////////////////////////////////////////////////////////////////////////////////
procedure make(zh: d: var e:arr); //生成路径,e[0]保存路径
var i,j,k: //上的节点个数
while d[zh]&&0 do
inc(i);e[i]:=zh:=d[zh];
inc(i);e[i]:= e[0]:=I;
主程序调用:求最短路径长度:初始化t,然后dijkstra(qi,t,c,d)
求路径:make(m,d,e) ,m是终点
迪杰斯特拉算法 -
Dijkstra算法的堆优化(PASCAL实现)
一、思考
我们可以发现,在实现步骤时,效率较低(需要O(n),使总复杂度达到O(n^2)。对此可以考虑用堆这种数据结构进行优化,使此步骤复杂度降为O(log(n))(总复杂度降为O(n log(n))。
二、实现
1. 将与源点相连的点加入堆,并调整堆。
2. 选出堆顶元素u(即代价最小的元素),从堆中删除,并对堆进行调整。
3. 处理与u相邻的,未被访问过的,满足三角不等式的顶点
1):若该点在堆里,更新距离,并调整该元素在堆中的位置。
2):若该点不在堆里,加入堆,更新堆。
4. 若取到的u为终点,结束算法;否则重复步骤2、3。
三、代码
procedure D
u,v,e,i:
(dis,sizeof(dis),$7e); //距离
fillchar(Inh,sizeof(Inh),false); //是否在堆中
fillchar(visit,sizeof(visit),false); //是否访问过
size:=0;
e:=last[s];
while e&&0 do //步骤1
u:=other[e];
if not(Inh[u]) then //不在堆里
inc(size);
heap[size]:=u;
dis[u]:=cost[e];
Loc[u]:= //Loc数组记录元素在堆中的位置
Inh[u]:=
Shift_up(Loc[u]); //上浮
if cost[e]&dis[u] then //在堆里
dis[u]:=cost[e];
Shift_up(Loc[u]);
Shift_down(Loc[u]);
e:=pre[e];
visit[s]:=
while true do
u:=heap[1]; //步骤2
if u= //步骤4
visit[u]:=
heap[1]:=heap[size];
dec(size);
Shift_down(1);
e:=last[u];
while e&&0 do //步骤3
v:=other[e];
if Not(visit[v]) and (dis[u]+cost[e]&dis[v]) then //与u相邻的,未被访问过的,满足三角不等式的顶点
if Inh[v] then //在堆中
dis[v]:=dis[u]+cost[e];
Shift_up(Loc[v]);
Shift_Down(Loc[v]);
else //不再堆中
inc(size);
heap[size]:=v;
dis[v]:=dis[u]+cost[e];
Loc[v]:=
Inh[v]:=
Shift_up(Loc[v]);
e:=pre[e];
(dis[t]);
迪杰斯特拉算法 -
Dijkstra算法讲解与C/C++实现
Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。
Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。
其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。
初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。
例如,对下图中的,应用Dijkstra算法计算从源顶点1到其它顶点间最短路径的过程列在下表中。
主题好好理解上图!
以下是具体的实现(C/C++):
/***************************************
* About: 有向图的Dijkstra算法实现
* Author: Tanky Woo
***************************************/
#include &iostream&
const int maxnum = 100;
const int maxint = 999999;
// 各数组都从下标1开始
int dist[maxnum]; // 表示当前点到源点的最短路径长度
int prev[maxnum]; // 记录当前点的前一个结点
int c[maxnum][maxnum]; // 记录图的两点间路径长度
int n, // 图的结点数和路径数
// n -- n nodes
// v -- the source node
// dist[ ] -- the distance from the ith node to the source node
// prev[ ] -- the previous node of the ith node
// c[ ][ ] -- every two nodes' distance
void Dijkstra(int n, int v, int *dist, int *prev, int c[maxnum][maxnum])
bool s[maxnum]; // 判断是否已存入该点到S集合中
for(int i=1; i&=n; ++i)
dist[i] = c[v][i];
s[i] = 0; // 初始都未用过该点
if(dist[i] == maxint)
prev[i] = 0;
prev[i] =
dist[v] = 0;
s[v] = 1;
// 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中
// 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度
// 注意是从第二个节点开始,第一个为源点
for(int i=2; i&=n; ++i)
int tmp =
int u =
// 找出当前未使用的点j的dist[j]最小值
for(int j=1; j&=n; ++j)
if((!s[j]) && dist[j]&tmp)
u = // u保存当前邻接点中距离最小的点的号码
tmp = dist[j];
s[u] = 1; // 表示u点已存入S集合中
// 更新dist
for(int j=1; j&=n; ++j)
if((!s[j]) && c[u][j]&maxint)
int newdist = dist[u] + c[u][j];
if(newdist & dist[j])
dist[j] =
prev[j] =
// 查找从源点v到终点u的路径,并输出
void (int *prev,int v, int u)
int que[maxnum];
int tot = 1;
que[tot] =
tot++;
int tmp = prev[u];
while(tmp != v)
que[tot] =
tot++;
tmp = prev[tmp];
que[tot] =
for(int i= i&=1; --i)
if(i != 1)
cout && que[i] && & -& &;
cout && que[i] &&
int main()
(&input.txt&, &r&, );
// 各数组都从下标1开始
// 输入结点数
cin &&
// 输入路径数
cin &&
int p, q, // 输入p, q两点及其路径长度
// 初始化c[][]为maxint
for(int i=1; i&=n; ++i)
for(int j=1; j&=n; ++j)
c[i][j] =
for(int i=1; i&= ++i)
cin && p && q &&
if(len & c[p][q]) // 有重边
c[p][q] = // p指向q
c[q][p] = // q指向p,这样表示无向图
for(int i=1; i&=n; ++i)
dist[i] =
for(int i=1; i&=n; ++i)
for(int j=1; j&=n; ++j)
printf(&%8d&, c[i][j]);
printf(&\n&);
Dijkstra(n, 1, dist, prev, c);
// 最短路径长度
cout && &源点到最后一个顶点的最短路径长度: & && dist[n] &&
// 路径
cout && &源点到最后一个顶点的路径为: &;
searchPath(prev, 1, n);
输入数据:
1 2 10
1 4 30
1 5 100
2 3 50
3 5 10
4 3 20
4 5 60
输出数据:
源点到最后一个顶点的最短路径长度: 60
源点到最后一个顶点的路径为: 1 -& 4 -& 3 -& 5
最后给出两道题目练手,都是直接套用模版就OK的:
1. 1874 畅通工程续
2.HDOJ 2544 最短路
为本词条添加和相关影像
互动百科的词条(含所附图片)系由网友上传,如果涉嫌侵权,请与客服联系,我们将按照法律之相关规定及时进行处理。未经许可,禁止商业网站等复制、抓取本站内容;合理使用者,请注明来源于。
登录后使用互动百科的服务,将会得到个性化的提示和帮助,还有机会和专业认证智愿者沟通。
您也可以使用以下网站账号登录:
此词条还可添加&
编辑次数:4次
参与编辑人数:4位
最近更新时间: 20:27:39
贡献光荣榜
扫描二维码用手机浏览词条
保存二维码可印刷到宣传品
扫描二维码用手机浏览词条
保存二维码可印刷到宣传品尼古拉·斯特拉的“利用大气电离层发电”的思想为什么现在还是无法运用呢?而且其原理又是什么呢?他建造了电塔,并且好像成功了.大气电离层和地面有着很大的电势差(电压),那么为什么_百度作业帮
尼古拉·斯特拉的“利用大气电离层发电”的思想为什么现在还是无法运用呢?而且其原理又是什么呢?他建造了电塔,并且好像成功了.大气电离层和地面有着很大的电势差(电压),那么为什么
尼古拉·斯特拉的“利用大气电离层发电”的思想为什么现在还是无法运用呢?而且其原理又是什么呢?他建造了电塔,并且好像成功了.大气电离层和地面有着很大的电势差(电压),那么为什么电离层上面的电荷没有一口气跑到大地上呢(形成电流)?【雷电是不是就是大气中的电压与地面接触产生电流而形成的现象呢?】为什么尼古拉建了一个塔就把电离层与大地之间的电压给利用了呢?其中有什么玄妙呢?【就好像埃菲尔铁塔就什么都没发生过】
尼古拉是利用铁塔给电离层发送了10HZ以下的低电频,使电离层中的电核产生共振,从而产生更大的电流在云层中,所以全世界不准使用低频电波,以免产生与电离层中的电核产生共振.
带点云层会跑的,哥们,别再幻想了,回家多看看书吧写小说要用诶= =~小说你就直接写一个“电离层发电机”呗主要是通古斯大爆炸啦【就是有一个假说说原因是因为尼古拉的实验,但是我无法描绘和想象其原理= =】(总不可能就说是一个“神秘的天灾制造器吧”)
我不好描绘这“电离层天灾制造器”的科学原理(最起码表面上说得过去啊~字数是钱啊)= =……...
小说你就直接写一个“电离层发电机”呗
主要是通古斯大爆炸啦【就是有一个假说说原因是因为尼古拉的实验,但是我无法描绘和想象其原理= =】(总不可能就说是一个“神秘的天灾制造器吧”)
我不好描绘这“电离层天灾制造器”的科学原理(最起码表面上说得过去啊~字数是钱啊)= =……
看一下电容远离
和 雨天产生雷电的原理
建个塔应该是增加局部的场强
击穿中间的空气
那个塔有什么功效?增加场强有什么作用?击穿空气又是怎么回事?
如果全世界都开始使用免费电能,那么世界经济都可能崩溃,到那时,能源问题解决了,世界还做什么贸易呢?当时 尼古拉想的是,全世界用免费的清洁能源,后来直接被美国给抹杀掉了!考虑了很多事情的;纪念伟大的交流电发明者斯特拉
还记得物理学中的磁通量密度标准单位吗?特斯拉(tesla,符号为T),今天就是他的生日。
,正是这位超级传奇的科学伟人,发明了交流电(AC),可至今却被绝大多数人遗忘,人们总是记得爱迪生点亮了小灯泡,事实上爱迪生发明的是直流电(DC),而在随后,特斯拉发明了交流电,远远超过直流电的能力,特斯拉曾经在当时的科技博览会上用交流电点亮9万个灯泡,全场人都被惊呆了。
为什么特斯拉被人们遗忘了呢?翻开历史,归咎于残酷的科学迫害和电流之争,出于利益的驱使,爱迪生对特斯拉进行持续的科学封杀,称其为科学另类,另一方面,当时的一些企业家利用特斯拉的发明赚足了钱财,并且利用它的技术欺骗民众。
最让人敬佩的是,特斯拉当时放弃了交流电的专利,使得交流电成为了一项免费使用的发明,并且坚持公开交流电原理,否则的话,当时任何发电厂每发明一匹的交流电,必须向特斯拉支付1美元的版税,这样的话,特斯拉绝对是当时的首富。然而,特斯拉的晚年就在贫穷和孤独中度过,几乎被人们遗忘。
特斯拉86岁时去世,在他死后,美国政府收缴了他的所有研究成果,封存为高级机密,并且删除了他的历史资料和档案,事实上,这是因为特斯拉还掌握了一些具有可怕能力的科学技术,!感兴趣的话你可以自己制作,如果你有足够强的能力,你可以放出几公里的闪电。
特斯拉还有其它很多发明,其中一些到现在人们都不知道原理,他的一生就像科幻电影里的怪博士,但是他并没有邪恶的动机,而恰恰是为了造福人类,他的梦想就是给人们提供取之不尽的能源,并且没有污染。
特斯拉绝对是“开源”领域的一位伟人,没有交流电的原理开放,不知道会对后世产生什么样的影响。
另外,可以说,爱迪生的营销和包装做得很好,以至于永远占据了人们的心智,人们总是会把爱迪生、发明家、电灯泡联系在一起,尽管后来特斯拉后来居上,也无法撼动人们的认知,事实上绝对多数的用户真的不懂交流电和直流电的区别,区别只有电的价格。
转载自思考,行动的博客 &
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}