前年一时脑热(理想很丰满,现实很骨感),写了这个最短路径优先的低效版本,且留着回忆吧。

spf.h

 #ifndef SPF_H_
#define SPF_H_ typedef struct {
int length;
char src;
char dst;
char prev_hop;
} dijkstra; #define MAX 1024
#define NODE_NUM 5
#define TRUE 1
#define FALSE 0 #endif

spf.c

 #include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <limits.h>
#include <time.h>
#include <sys/timeb.h>
#include "spf.h" dijkstra DIJK[NODE_NUM][NODE_NUM] = {};
char NODES[NODE_NUM] = {'A', 'B', 'C', 'D', 'E'};
int P_NDS[NODE_NUM] = {};
int U_NDS[NODE_NUM] = {}; int distance(char src, char dst);
void debug(char* fmt,...);
void spf_dijkstra_init();
void spf_show_dijkstra_matrix(int top);
dijkstra* spf_shortest_path_cost(char src, char dst);
void spf_main(int src_top);
int in_pnd_sets(char src);
void spf_pu_sets_init();
int spf_find_candidate_node(int src_top, int top);
int spf_calc_next_hop(int src_top, int top, int min_idx);
void time_show(); int main(int argc, char **argv) {
int i;
//time_show();
spf_dijkstra_init();
for (i=; i<NODE_NUM; i++) {
spf_pu_sets_init();
spf_main(i);
//spf_show_dijkstra_matrix(i);
}
//time_show();
return ;
} void spf_pu_sets_init() {
memset(P_NDS, , sizeof(P_NDS));
memset(U_NDS, , sizeof(U_NDS));
} void spf_main(int src_top) {
int top = src_top;
int min_node_id = -;
int loop = ; if (top >= NODE_NUM || top < ) {
debug("input error src_top = %d, input again plz \n");
return;
} P_NDS[top] = TRUE;
while(TRUE) {
if (loop == NODE_NUM) break;
loop++; min_node_id = spf_find_candidate_node(src_top, top);
if (min_node_id == -) continue;
top = spf_calc_next_hop(src_top, top, min_node_id);
if (top< || top>NODE_NUM) continue;
P_NDS[top] = TRUE;
}
return;
} int spf_find_candidate_node(int src_top, int top) {
int min_idx = -;
int min_cost = MAX; for (int i=; i<NODE_NUM; i++) {
if (TRUE == P_NDS[i]) continue; // 已经计算过路由的就不在计算 int d1 = distance(NODES[top], NODES[i]);
if (MAX == d1 || == d1) continue; U_NDS[i] = TRUE;
dijkstra* dij_dst = spf_shortest_path_cost(NODES[src_top], NODES[i]);
dijkstra* dij_hop = spf_shortest_path_cost(NODES[src_top], NODES[top]); if (NULL == dij_dst || NULL == dij_hop) continue; // 如果源顶点与当前节点的距离 > 源顶点与当前顶点的距离 + 当前顶点与当前节点的距离,
// 则设置当前顶点为当前节点的上一跳节点
// 'S' 表示没有设置过上一跳节点
if (dij_dst->length > d1+dij_hop->length || dij_dst->prev_hop == 'S') {
dij_dst->prev_hop = NODES[top];
} if (d1 < min_cost) {
min_cost = d1;
min_idx = i;
}
} return min_idx;
} int spf_calc_next_hop(int src_top, int top, int min_idx) {
for (int i=; i<NODE_NUM; i++) {
if (FALSE == U_NDS[i]) continue;
int d1 = distance(NODES[src_top], NODES[i]);
int d2 = distance(NODES[top], NODES[i]); if ( == d2) continue;
dijkstra* dij_top = spf_shortest_path_cost(NODES[src_top], NODES[top]);
int d3 = d2 + dij_top->length;
dijkstra* dij_dst = spf_shortest_path_cost(NODES[src_top], NODES[i]);
if (!dij_dst) continue; // 如果源顶点到当前节点的已经过计算的最短路径距离小于直接计算源顶点与当前节点距离
//,则使用最短路径距离
if (dij_dst->length < d1) d1 = dij_dst->length; // 如果源顶点与当前顶点的距离+当前顶点到当前节点的距离
// 小于直接计算源顶点与当前节点距离,
// 则把当前顶点设置为当前的节点上一跳
if ( < d3 && d3 < MAX && d3 <= d1) {
dij_dst->prev_hop = NODES[top];
dij_dst->length = d3;
U_NDS[i] = FALSE;
}
// 如果当前节点的最短路径距离小于当前顶点计算的距离,
// 则调整当前节点上一跳,重新开始最短路由运算
else if (d1 > && d1 < d3 && d3 < MAX) {
int d = distance(dij_dst->src, dij_dst->dst);
// 如果源顶点与目标节点是直连,并且距离小于最短路径距离,
// 则设置上一条节点为源顶点
if (MAX!=d && d<dij_dst->length)
dij_dst->prev_hop = dij_dst->src; P_NDS[top] = FALSE;
U_NDS[top] = TRUE;
min_idx = i;
}
}
return min_idx;
} int in_pnd_sets(char src) {
int i;
for (i=; i<NODE_NUM; i++)
if (NODES[i] == src && P_NDS[i] == TRUE)
return TRUE;
return FALSE;
} void spf_dijkstra_init() {
int i,j;
for (i=; i<NODE_NUM; i++) {
for (j=; j<NODE_NUM; j++) {
DIJK[i][j].length = distance(NODES[i], NODES[j]);
DIJK[i][j].src = NODES[i];
DIJK[i][j].dst = NODES[j];
DIJK[i][j].prev_hop = DIJK[i][j].length == ? NODES[i] : 'S';
}
}
return;
} void spf_show_dijkstra_matrix(int top) {
int i,j;
for (i=; i<NODE_NUM; i++) {
for (j=; j<NODE_NUM; j++) {
if (top == i && DIJK[i][j].src != DIJK[i][j].dst)
printf("len=%d src=%c dst=%c prev=%c\n",
DIJK[i][j].length, DIJK[i][j].src,
DIJK[i][j].dst, DIJK[i][j].prev_hop);
}
}
printf("\n");
return;
} dijkstra* spf_shortest_path_cost(char src, char dst) {
dijkstra* dij = &DIJK[][];
for (int k=; k<NODE_NUM*NODE_NUM; k++,dij++) {
if (dij->src == src && dij->dst == dst)
return dij;
} return NULL;
} int distance(char src, char dst) {
if (src == dst) return ;
if ('A' == src && 'B' == dst) return ;
if ('B' == src && 'A' == dst) return ;
if ('A' == src && 'C' == dst) return ;
if ('C' == src && 'A' == dst) return ;
if ('B' == src && 'D' == dst) return ;
if ('D' == src && 'B' == dst) return ;
if ('B' == src && 'E' == dst) return ;
if ('E' == src && 'B' == dst) return ;
if ('C' == src && 'E' == dst) return ;
if ('E' == src && 'C' == dst) return ;
if ('D' == src && 'E' == dst) return ;
if ('E' == src && 'D' == dst) return ;
return MAX;
}

重复造轮子系列--dijkstra算法的更多相关文章

  1. 重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关

    重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关 引言 重复造轮子系列是自己平时的一些总结.有的轮子依赖社区提供的轮子为基础,这里把使用过程的一些觉得有意思的做个分享.有些思路或者方法在 ...

  2. 重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印

    重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端 ...

  3. 重复造轮子系列--内存池(C语言)

    这个代码是我上个公司工作项目的里面内存管理(基于伙伴算法)的一个简化又简化的版本. 因为没有内存边界检查: 因为没有内存使用统计: 因为没有考虑线程安全: 因为没有内存分配操作的具体文件位置信息: 因 ...

  4. 重复造轮子之RSA算法(一) 大素数生成

    出于无聊, 打算从头实现一遍RSA算法 第一步, 大素数生成 Java的BigInteger里, 有个现成的方法 public static BigInteger probablePrime(int ...

  5. 重复造轮子系列--字符串处理(C语言)

    这些字符代码是以前写的,源于很久很久以前的一个VC++项目,在当时的部门编程比赛里因为用了项目代码的xsplit函数,万万没想到,那个做了几年的项目里面居然有坑..xsplit函数居然不能split连 ...

  6. Meteva——让预报检验不再重复造轮子

    更多精彩,请点击上方蓝字关注我们! 检验是什么?****预报准确率的客观表达 说到天气预报,你最先会想到什么? 早上听了预报,带了一天伞却没下一滴雨的调侃? 还是 "蓝天白云晴空万里突然暴风 ...

  7. 避免重复造轮子的UI自动化测试框架开发

    一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...

  8. GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。

    1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便 ...

  9. 第27篇 重复造轮子---模拟IIS服务器

    在写程序的时候,重复造轮子是程序员的一个大忌,很多人对重复造轮子持有反对的态度,但是我觉得这个造轮子的过程,是对于现有的知识的一个深入的探索的过程,虽然我们不可能把轮子造的那么的完善,对于现在有的东西 ...

随机推荐

  1. hadoop分类输出

    import org.apache.hadoop.io.Text; import java.io.IOException;import java.util.Iterator;import java.u ...

  2. elsevier期刊要求翻译

    百度文库 http://wenku.baidu.com/view/e20a27e84afe04a1b071de4e.html 官网文档 http://www.elsevier.com/journals ...

  3. vim常用操作整理

    一.删除操作 :%s/r//g 删除DOS方式的回车^M :%s= *$== 删除行尾空白 :%s/^(.*)n1/1$/ 删除重复行 :%s/^.pdf/new.pdf/ 只是删除第一个pdf :% ...

  4. chisel(安装)

    github地址 先安装homeBrew ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/m ...

  5. gdb几个操作

    如果进程转为守护进程,可设置如下跟进子进程 set follow-fork-mode child 输出变量/函数/返回值有print, call, display,自行选择 对于打印value has ...

  6. 第33题:LeetCode255 Verify Preorder Sequence in Binary Search Tree 验证先序遍历是否符合二叉搜索树

    题目 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 考点 1.BST 二叉搜索树 2.递归 思路 1.后序 ...

  7. using namespace std 是什么意思?

    摘录CSDN上面大牛的回答简要意思就是使用标准库,想知道更清楚的继续读下面的. using   namespace   std   意思:   using   和namespace都是C++的关键词. ...

  8. linux下后台运行jar包

    #当前窗口退出 项目关闭$ java -jar test.jar #当前窗口关闭 项目关闭$ nohup java -jar test.jar &#当前窗口关闭 项目不关闭$ nohup ja ...

  9. httpd虚拟主机、站点访问控制、基于用户的访问控制、持久链接等应用配置实例

    httpd配置内容 httpd2.2 配置文件: /etc/httpd/conf/httpd.conf /etc/httpd/conf.d/*.conf 服务脚本: /etc/rc.d/init.d/ ...

  10. Python代码结构——顺序、分支、循环

    ## 顺序结构 - 按照从上到下的顺序,一条语句一条语句的执行,是最基本的结构 ## 分支结构 if condition: statement statement ... elif condition ...