重复造轮子系列--dijkstra算法
前年一时脑热(理想很丰满,现实很骨感),写了这个最短路径优先的低效版本,且留着回忆吧。
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算法的更多相关文章
- 重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关
重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关 引言 重复造轮子系列是自己平时的一些总结.有的轮子依赖社区提供的轮子为基础,这里把使用过程的一些觉得有意思的做个分享.有些思路或者方法在 ...
- 重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印
重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端 ...
- 重复造轮子系列--内存池(C语言)
这个代码是我上个公司工作项目的里面内存管理(基于伙伴算法)的一个简化又简化的版本. 因为没有内存边界检查: 因为没有内存使用统计: 因为没有考虑线程安全: 因为没有内存分配操作的具体文件位置信息: 因 ...
- 重复造轮子之RSA算法(一) 大素数生成
出于无聊, 打算从头实现一遍RSA算法 第一步, 大素数生成 Java的BigInteger里, 有个现成的方法 public static BigInteger probablePrime(int ...
- 重复造轮子系列--字符串处理(C语言)
这些字符代码是以前写的,源于很久很久以前的一个VC++项目,在当时的部门编程比赛里因为用了项目代码的xsplit函数,万万没想到,那个做了几年的项目里面居然有坑..xsplit函数居然不能split连 ...
- Meteva——让预报检验不再重复造轮子
更多精彩,请点击上方蓝字关注我们! 检验是什么?****预报准确率的客观表达 说到天气预报,你最先会想到什么? 早上听了预报,带了一天伞却没下一滴雨的调侃? 还是 "蓝天白云晴空万里突然暴风 ...
- 避免重复造轮子的UI自动化测试框架开发
一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...
- GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。
1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便 ...
- 第27篇 重复造轮子---模拟IIS服务器
在写程序的时候,重复造轮子是程序员的一个大忌,很多人对重复造轮子持有反对的态度,但是我觉得这个造轮子的过程,是对于现有的知识的一个深入的探索的过程,虽然我们不可能把轮子造的那么的完善,对于现在有的东西 ...
随机推荐
- numpy 矩阵运算
8.2 矩阵(Matrix)对象 Matrix类型继承于ndarray类型,因此含有ndarray的所有数据属性和方法.Matrix类型与ndarray类型有六个重要的不同点,当你当Matrix对象当 ...
- 等待唤醒机制,UDP通信和TCP通信
等待唤醒机制 通过等待唤醒机制使各个线程能有效的利用资源. 等待唤醒机制所涉及到的方法: wait() :等待,将正在执行的线程释放其执行资格 和 执行权,并存储到线程池中. notify():唤醒, ...
- 第6章 新建工程-寄存器版—零死角玩转STM32-F429系列
第6章 新建工程—寄存器版 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fireg ...
- ASP.NET中无刷新分页
上次介绍了我们代码写的刷新分页,这次就来说说无刷新分页. 这次我们是在上次的基础上改动了一些,我们都知道想要无刷新,就需要Ajax,在我们的ASP.NET中AJax是和一般处理程序配合着用的. 无刷新 ...
- HTML第二章:列表,表格,媒体元素
第二章:列表,表格,媒体元素 列表:有三种,有序列表,无序列表,定义列表 1.有序列表:<ol></ol> 列表项:<li></li&g ...
- 一篇SSM框架整合友好的文章(一)
转载请标明出处: http://blog.csdn.net/forezp/article/details/53730333 本文出自方志朋的博客 最近实在太忙,之前写的<rxjava系列文章&g ...
- MySQL-常用的存储引擎
MySQL-常用的存储引擎 存储引擎 事务 锁粒度 主要应用 忌用 MyISAM 不支持 支持并发插入的表级锁 select,insert 读写操作频繁 MRG_MYISAM 不支持 支持并发插入的表 ...
- Xcode 中 pch 文件配置 - iOS
一.简介 首先 pch 文件(即:Prefix Header)是一种预编译文件,在 Xcode 6 之前创建新的工程则会自动将该文件一起创建出来,但在 Xcode 6 之后苹果官方则默认将自动创建的方 ...
- 开发常用宏 - iOS
以下是一些开发中会经常用到的宏,简单的进行了整理,为了今后可以更加方便的使用,从而提升开发的效率,不为此搭进去更多时间. 也希望有大家可以补充,从而使其更加强加! /** * 开发常用宏相关 */ # ...
- 搭建私有maven库发布及使用流程
一:背景 Apache Maven是当Java技术栈前最流行的项目管理工具,它提供了一系列方便快捷的命令帮助程序员们进行Java工程的开发工作.Maven服务器位于美国,由于出国带宽和众多因素,在国内 ...