我们有一个有向图G =(V,E),其中E中的每个边(u,v)在R中具有相对值r(u,v)并且0 <= r(u,v)&lt ; = 1,表示在通信信道上从顶点u到顶点v的可靠性。
考虑r(u,v)从u到v的chanel不会使转移失败的概率,并且概率是独立的。 我想编写一个有效的算法,找到两个给定节点之间最可靠的路径。
我尝试了以下内容:
DIJKSTRA(G,r,s,t)
1. INITIALIZE-SINGLE-SOURCE(G,s)
2. S=Ø
3. Q=G.V
4. while Q != Ø
5. u<-EXTRACT-MAX(Q)
6. if (u=t) return d[t]
7. S<-S U {u}
8. for each vertex v in G.Adj[u]
9. RELAX(u,v,r)
INITIAL-SINGLE-SOURCE(G,s)
1. for each vertex v in V.G
2. d[v]=-inf
3. pi[v]=NIL
4. d[s]=1
RELAX(u,v,r)
1. if d[v]<d[u]*r(u,v)
2 d[v]<-d[u]*r(u,v)
3. pi[v]<-u
我想找到算法的复杂性。
INITIALIZE-SINGLE-SOURCE(G,s)的时间复杂度为O(| V |)。 线4的时间复杂度是O(1)。 线5的时间复杂度为O(| V |)。 线7的时间复杂度为O(log(| V |))。 线8的时间复杂度是O(1)。 命令S&lt; -S U {u}的时间复杂度是多少? 第10行以总O(Σ_{v \ in V} deg(v))= O(E)次执行,RELAX的时间复杂度为O(1)。
因此算法的时间复杂度等于线(3-9)+ O(E)的时间复杂度。 工会的时间复杂性是什么?
答案 0 :(得分:2)
我认为解决方案应该基于经典的Dijkstra算法(其复杂性众所周知),正如您所建议的那样,但是在您的解决方案中,您错误地定义了“最短路径”问题。
注意A和B的概率是p(A)* p(B)(如果它们是独立的)。因此,您应该找到一条路径,其乘法的边是最大化。而Dijkstra算法找到和边缘最小化的路径。
要解决此问题,您应将边缘的权重定义为:
R *(u,v)= -log(R(u,v))
通过引入对数,可以将乘法问题转换为加法。
答案 1 :(得分:2)
因此算法的时间复杂度等于时间 线条的复杂性(3-9)+ O(E)。这是时间的复杂性 工会?
不,这不是联盟的复杂性,如果你使用哈希表,联盟可以非常高效地完成。此外,由于您仅将S
用于联合,因此似乎是多余的。
算法的复杂性也在很大程度上取决于你的EXTRACT-MAX(Q)
函数(通常它是Q
的大小的对数,因此每次迭代的logV),以及RELAX(u,v,r)
上的Q
通常也是O(E+VlogV)
大小的对数,因为您需要更新优先级队列中的条目。)
正如预期的那样,这使我们得到原始Dijkstra算法的复杂性,即O(ElogV)
或typedef struct {
unsigned char * ustr;
int height;
}node;
void node_init(node * n, int r) {
int i;
n->ustr = malloc((r + 1) * sizeof(unsigned char));
for (i = 0; i < r; i++) {
(n->ustr)[i] = random() & 0xff;
}
(n->ustr)[r] = 0;
n->height = -1;
}
void node_destroy(node * n) {
free(n->ustr);
n->height = -1;
}
int main() {
FILE* file_ptr = fopen("file1", "w+");
node n0;
node_init(&n0,2);
fwrite(&n0, sizeof(node), 1, file_ptr);
fclose(file_ptr);
node_destroy(&n0);
return 0;
}
,具体取决于您的优先级队列的实现。