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

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. 简单使用hibernate(idea中使用)

    首先创建一个maven项目 创建成功后,进行创建数据库的表 CREATE TABLE BOOK( ID INT AUTO_INCREMENT PRIMARY KEY, NAME ), NUMBER i ...

  2. CDH4.5.0源代码编译

    Unable to load native-hadoop library for your platform解决 安装maven 1 cmake-2.8.12.1.tar.gz cd cmake-2. ...

  3. runit git-daemon-run 等错误

    正在处理用于 man-db (2.7.5-1) 的触发器 ... 正在设置 runit (2.1.2-3ubuntu1) ... start: 无法连接到 Upstart: Failed to con ...

  4. iOS程序猿如何快速掌握 PHP,化身"全栈攻城狮"?

    这是一篇以 iOS 开发人员的视角写给广大iOS 程序猿的 PHP 入门指南.在这篇文章里我努力去发掘 objectiv-c 与 php 之间的共性,来帮助有一定 iOS 开发经验的攻城狮来快速上手一 ...

  5. Swift项目,适配遇到的问题

    Swift4.x 控制器自带xib加载在iOS8系统崩溃 // MARK: - 解决控制器自带xib加载在iOS8系统崩溃的问题.iOS8.x,需要给控制器的xib重写一下init 方法 overri ...

  6. phonegap二维码扫描插件

    原文出处:http://rensanning.iteye.com/blog/2034026 谈谈我使用这个的体会吧; git地址 https://github.com/wildabeast/Barco ...

  7. Mysql: pt-table-checksum 和 pt-table-sync 检查主从一致性,实验过程

    一.安装 percona 包 1.安装仓库的包 https://www.percona.com/doc/percona-repo-config/yum-repo.html sudo yum insta ...

  8. 图解HTTP总结(4)——返回结果的HTTP状态码

    HTTP状态码负责表示客户端HTTP请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作. 状态码的类别 2XX 成功 200 OK 表示从客户端发来的请求在服务器端被正常处理了. 在响应 ...

  9. caioj:1093: 并查集2(scy的删边问题) C++

    题目描述 [题目描述] 读入一个无向图(可能含有多个连通分支),输出最多能删掉多少条边,而不改变这个图任意两点的连通性(原来连通的两个点依然连通,不连通的依然不连通). [输入格式] 第一行为图的顶点 ...

  10. C语言进阶——enum, sizeof, typedef 分析11

    枚举类型的使用方法: enum是C语言的 一种自定义类型 enum值是可以根据需要自定义的整型值 第一个enum的值默认为0 默认情况下的enum值是在前一个定义值的基础上加 1 enum类型的变量只 ...