有向无环图两点之间的路径数目(算法导论22.4-2)
来源:互联网 发布:mac 文件锁定 编辑:程序博客网 时间:2024/05/17 02:26
有向无环图G=(V,E),求其点s和e之间的路径数目。此题首先要以点s开始作DFS,得到从s为起点的所有可达点的一顶DFS树,但这个路径数目需要详细参详。
定义P(x),表示点s到点x的路径数目,P(s)=1,即s到自身有一条路径,其余的所有路径数目都初始化为0。
路径从s到达点x,则必须到达x的上一层结点,假设以x为终点的上一层结点有n个,即a1,a2,...,an,由加法定律可知P(x)= P(a1) + P(a2) + ... + P(an),这是一个从顶向下的递推过程,有点类似于动态规划。
综上,我们只要获取任意一点的入邻接表(也称逆邻接表),由图G获取其转置GT,其中保存着任意一点的上一层结点。然后再从顶向下递推,正好利用拓扑排序获得的序列,因为由拓扑排序的定义可以保证结点的顺序关系,因此递推有效。以下的算法步骤:
(1) 由图G获取其转置图GT,以得到所有点的入邻接表
(2) 以点s开始作DFS,得到从点s到达点e的拓扑序列
(3) 以此拓扑序列为顺序,逐个获取P值,最终得到P(e),即s到e的路径数目
图中实线为tree edge,曲线为forward和cross edge,从p到v的路径数目,递推过程如下:
P(p) = 1
P(o) = P(p) = 1
P(s) = P(p) + P(o)= 2
P(r) = P(o) +P(s) = 3
P(y) = P(r) = 3
P(v) = P(y) +P(o) = 4
步骤(1) 代码如下
static int graph_add_edge(struct link_graph *G, int uindex, int vindex){ struct link_edge *e = NULL; struct link_vertex *u = G->v + uindex; e = malloc(sizeof(struct link_edge)); if (!e) return -1; e->vindex = vindex; e->type = EDGE_NONE; list_add(&e->node, &u->head); return 0;}struct link_graph* graph_transpos(struct link_graph *G){ int i = 0; struct link_edge *e = NULL; struct link_vertex *u = NULL; struct link_graph *GT = NULL; GT = malloc(sizeof(struct link_graph)); if (!GT) return NULL; GT->v = malloc(G->vcount * sizeof(struct link_vertex)); if (!GT->v) { free(GT); return NULL; } GT->vcount = G->vcount; GT->ecount = G->ecount; for (i = 0;i < GT->vcount;i++) { u = GT->v + i; u->vindex = i; INIT_LIST_HEAD(&u->head); } for (i = 0;i < G->vcount;i++) { u = G->v + i; list_for_each_entry(e, &u->head, node) { graph_add_edge(GT, e->vindex, i); } } return GT;}
步骤(2) 代码如下
void DFS_visit_topo(struct link_graph *G, struct link_vertex *u, int *color, struct list_head *head){ struct link_edge *le = NULL; color[u->vindex] = COLOR_GRAY; list_for_each_entry(le, &u->head, node) { if (color[le->vindex] == COLOR_WHITE) { DFS_visit_topo(G, G->v + le->vindex, color, head); le->type = EDGE_TREE; } else if (color[le->vindex] == COLOR_GRAY) { le->type = EDGE_BACK; printf("G has cycle and cannot topology sort\n"); } } color[u->vindex] = COLOR_BLACK; list_add(&u->qnode, head);}int graph_topo_sort(struct link_graph *G, int s, struct list_head *thead){ int i; int *color; color = malloc(sizeof(int) * G->vcount); for (i = 0;i < G->vcount;i++) { color[i] = COLOR_WHITE; } DFS_visit_topo(G, G->v + s, color, thead); free(color); return 0;}
步骤(3) 代码如下
int graph_count_path(struct link_graph *G, int s, int end){ int *P; struct list_head thead; struct link_vertex *u = NULL, *ut = NULL; struct link_edge *e = NULL; struct link_graph *GT = NULL; GT = graph_transpos(G); if (GT == NULL) return -1; P = malloc(G->vcount * sizeof(int)); memset(P, 0, G->vcount * sizeof(int)); P[s] = 1; INIT_LIST_HEAD(&thead); graph_topo_sort(G, s, &thead); printf("The topology sort from %d is below:\n", s); list_for_each_entry(u, &thead, qnode) { printf("%4d ", u->vindex); if (u->vindex == s) continue; ut = GT->v + u->vindex; list_for_each_entry(e, &ut->head, node) { P[u->vindex] += P[e->vindex]; } if (u->vindex == end) { printf("\n\nThere are %d paths from %d to %d\n", P[end], s, end); break; } } link_graph_exit(GT); return 0;}
- 有向无环图两点之间的路径数目(算法导论22.4-2)
- 算法导论22.4-2 有向无环图的路径数目
- Matalab代码 实现 Dijkstra求 有向图及无向图之间,任意两点之间的最短路径
- 有向图的传递闭包,两点间最短路径的Floyd算法的变化.
- 有向无环图中, 两点间的简单路径数
- 【图】:有向图中两点间的路径
- 图--有向无负权回路的单源最短路径 DAG 算法导论p365
- 算法导论 思考题 15-1(有向无环图中的最长简单路径)
- 有向有环图两点间路径问题
- Floyed算法求两点之间的最短路径
- ACM-Floyed算法求两点之间的最短路径
- 图算法之求两点之间的所有路径(java)
- 求有向网中任意一对顶点之间的最短路径 Floyd算法
- 图论算法-求(有向)图中任意两点间所有路径
- 图论算法-求(有向)图中任意两点间所有路径
- 【算法导论】有向图的深度优先搜索遍历
- 【算法导论】有向图的可达矩阵
- 搜索无向图中两点之间的所有路径(java)
- 如何才能成为优秀的产品经理(一)
- 窗口站&桌面
- Magento: 移除分类列表的排序Sort by下拉列表里面的第一个选项:position
- Mysql批量插入随机数据改进版_设置表主键为自增,免得主键冲突
- MongoDB常用方法
- 有向无环图两点之间的路径数目(算法导论22.4-2)
- SDJZU 出租车费
- Cookie与Session
- 栈的链式存储结构及其基本运算的实现
- 如何才能成为优秀的产品经理(二)
- SQL Server 2005 COM+ 目录要求警告
- 看电视(今年暑假不AC)
- epoll使用详解(精髓)
- 浅谈PHP在各系统平台下的换行符