最近自己陷入了很长时间的学习和思考之中,突然发现好久没有更新博文了,于是便想更新一篇。

  这篇文章是我之前程序设计语言课作业中一段代码,用scheme语言实现单源最段路算法。当时的我,花了一整天时间,学习了scheme并实现了SPFA算法,那天实现之后感觉很有成就感~在这里贴出来,以飨读者。


  突然发现博客园不支持scheme语言,于是只能放弃高亮了。不得不说,scheme代码有没有高亮差别好大……

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 题目:单源最短路,输入数据给定
;;
;; 作者:卢奇
;; 学号:5130309680
;; 邮箱:icedream@sjtu.edu.cn
;;
;; 算法:SPFA(简化版)
;;
;; 代码结构:共三大部分——
;; 开始是一些语法糖,
;; 然后是SPFA算法的实现,
;; 最后是主体部分,调用了SPFA算法并输出结果。
;;
;; 备注:代码备注共有两种——
;; 1. 代码的三大部分,各自开头有一段备注
;; 2. 代码的两个主体部分,内部穿插了一些备注
;; 其中,两个主体部分是指:代码主体部分 以及 SPFA算法的主体部分(即SPFA函数)
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (begin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 这里是为后面代码定义的一些语法糖。
;;
;; 为了可读性,我做了一个“下标变换”:
;; 题目图中6个点,存储为0~5,但供操作的API对外设计成1~6的假象,简化思路
;;
;; 有一维数组、二维数组、队列和逻辑运算几方面,具体如下所示:
;; 1. 根据下标该值,构造新数组:change, change2
;; 2. 根据下标赋值(+下标变换):set, set2
;; 3. 根据下标取值(+下标变换):get, get2
;; 4. 入队、出队:push, pop
;; 5. 逻辑运算(二元与、二元或):and, or
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (change a i x)
(if (eqv? i 0)
(cons x (cdr a))
(cons (car a) (change (cdr a) (- i 1) x))))
(define (change2 a i j x)
(if (eqv? i 0)
(cons (change (car a) j x) (cdr a))
(cons (car a) (change2 (cdr a) (- i 1) j x))))
(define-syntax set
(syntax-rules ()
([set a i x] (set! a (change a (- i 1) x)))))
(define-syntax set2
(syntax-rules ()
([set2 a i j x]
(begin
(set! a (change2 a (- i 1) (- j 1) x))
(set! a (change2 a (- j 1) (- i 1) x))))))
(define-syntax get
(syntax-rules ()
([get a i] (list-ref a (- i 1)))))
(define-syntax get2
(syntax-rules ()
([get2 a i j] (list-ref (list-ref a (- i 1)) (- j 1))))) (define-syntax push
(syntax-rules ()
([push Q x] (set! Q (append Q (list x))))))
(define-syntax pop
(syntax-rules ()
([pop Q]
(let ([x (car Q)])
(set! Q (cdr Q))
x)))) (define-syntax and
(syntax-rules ()
([and Ea Eb]
(if (eqv? Ea #t)
(if (eqv? Eb #t) #t #f)
#f))))
(define-syntax or
(syntax-rules ()
([or Ea Eb]
(if (eqv? Ea #t)
#t
(if (eqv? Eb #t) #t #f))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 此为SPFA算法部分(简化版)
;;
;; 其中SPFA函数是主体,其调用了update-all函数,后者又调用了update函数。
;;
;; 注:之所以称之为简化版,是因为本来SPFA的入队应该去重的,但被我给省了。
;; 不过本题中并不要求速度、也不影响正确性,写不写也就无所谓了。
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (update map d Q u allv)
(cond
[(not (eqv? allv null))
(let ([v (car allv)] [lastv (cdr allv)])
; (newline)
; (display "an update --") (newline)
; (display "d: ") (display d) (newline)
; (display "Q: ") (display Q) (newline)
; (display "u: ") (display u) (newline)
; (display "v: ") (display v) (newline)
; (display "allv: ") (display allv) (newline)
(cond
[(and (not (eqv? (get2 map u v) #f)) (or (eqv? (get d v) #f) (< (+ (get d u) (get2 map u v)) (get d v))))
(begin
(set d v (+ (get d u) (get2 map u v)))
(push Q v))])
(update map d Q u lastv))]
[else (list d Q)])) (define (update-all map d Q)
(if (eqv? Q null)
d
(let ([u (pop Q)])
(define tmp (update map d Q u (list 1 2 3 4 5 6)))
(set! d (car tmp))
(set! Q (cadr tmp))
(update-all map d Q)))) (define (SPFA map s)
; 初始化SPFA中的数组
(define d (make-list 6 #f))
(set d s 0)
(define Q null)
(push Q s)
; 输出初始化的数组,仅供调试
(display "d: ") (display d) (newline)
(display "Q: ") (display Q) (newline)
; 计算由s出发的单源最短路,并返回计算出的结果
(update-all map d Q)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 题目主函数在此
;;
;; 本题所有的IO都在这里给出了,一目了然。
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 建图 称为map
(define map (make-list 6 (make-list 6 #f)))
(set2 map 1 2 7)
(set2 map 1 3 9)
(set2 map 1 6 14)
(set2 map 2 4 15)
(set2 map 2 3 10)
(set2 map 3 4 11)
(set2 map 3 6 2)
(set2 map 4 5 6)
(set2 map 5 6 9)
; 通过简化的SPFA算法计算最短路
(define d (SPFA map 1))
; 输出答案
(display "last-d: ") (display d) (newline)
(display "result: ") (display (get d 5)) (newline))

用scheme语言实现SPFA算法(单源最短路)的更多相关文章

  1. Dijkstra算法——单源最短路算法

    一.介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他各个节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 适用于有 ...

  2. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  3. 模板C++ 03图论算法 1最短路之单源最短路(SPFA)

    3.1最短路之单源最短路(SPFA) 松弛:常听人说松弛,一直不懂,后来明白其实就是更新某点到源点最短距离. 邻接表:表示与一个点联通的所有路. 如果从一个点沿着某条路径出发,又回到了自己,而且所经过 ...

  4. 2018/1/28 每日一学 单源最短路的SPFA算法以及其他三大最短路算法比较总结

    刚刚AC的pj普及组第四题就是一种单源最短路. 我们知道当一个图存在负权边时像Dijkstra等算法便无法实现: 而Bellman-Ford算法的复杂度又过高O(V*E),SPFA算法便派上用场了. ...

  5. spfa 单源最短路究极算法

    学习博客链接:SPFA 求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm.     SPFA算法是西南交通大学段凡丁于1994年发表的.    从名字我 ...

  6. [ACM_图论] Domino Effect (POJ1135 Dijkstra算法 SSSP 单源最短路算法 中等 模板)

    Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...

  7. 【算法】单源最短路——Dijkstra

    对于固定起点的最短路算法,我们称之为单源最短路算法.单源最短路算法很多,最常见的就是dijkstra算法. dijkstra主要用的是一种贪心的思想,就是说如果i...s...t...j是最短路,那么 ...

  8. 【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home

    https://vjudge.net/contest/66569#problem/A http://blog.csdn.net/wangjian8006/article/details/7871889 ...

  9. 单源最短路_SPFA_C++

    当我们需要求一个点到其它所有点的最短路时,我们可以采用SPFA算法 代码特别好写,而且可以有环,但是不能有负权环,时间复杂度是O(α(n)n),n为边数,α(n)为n的反阿克曼函数,一般小于等于4 模 ...

随机推荐

  1. Effective Java 56 Adhere to generally accepted naming conventions

    Typographical naming conventions Identifier Type Type Examples Package com.google.inject, org.joda.t ...

  2. PS网页设计教程XXVII——设计一个大胆和充满活力的作品集

    作为编码者,美工基础是偏弱的.我们可以参考一些成熟的网页PS教程,提高自身的设计能力.套用一句话,“熟读唐诗三百首,不会作诗也会吟”. 本系列的教程来源于网上的PS教程,都是国外的,全英文的.本人尝试 ...

  3. 算法(二)之遗传算法(SGA)

    算法(二)之遗传算法(SGA) 遗传算法(Genetic Algorithm)又叫基因进化算法或进化算法,是模拟达尔文的遗传选择和自然淘汰的生物进化过程的计算模型,属于启发式搜索算法一种. 下面通过下 ...

  4. python enumerate 函数用法

    enumerate字典上是枚举.列举的意思.   C语言中关键字enum也是enumerate的缩写.   python中enumerate方法,返回一个enumerate类型.参数一般是可以遍历的的 ...

  5. Go

    一.简介 https://zh.wikipedia.org/wiki/Go 二.安装 1)低版本 http://blog.sina.com.cn/s/blog_59cc90640102xm8r.htm ...

  6. Azure 上为Liunx VM 挂载File类型的存储。

    1. Create a storage account in Azure, copy the storage account endpoint URL (with postfix of "f ...

  7. dotnet use regex two samples

    One sample is used to replace double quote from words which encapsulated by csvwriter , you know csv ...

  8. openfire+asmack搭建的安卓即时通讯(一) 15.4.7

    最进开始做一些android的项目,除了一个新闻客户端的搭建,还需要一个实现一个即时通讯的功能,参考了很多大神成型的实例,了解到operfire+asmack是搭建简易即时通讯比较方便,所以就写了这篇 ...

  9. hdu 5802 Windows 10 贪贪贪

    传送门:hdu 5802 Windows 10 题意:把p变成q:升的时候每次只能升1,降的时候如果前一次是升或者停,那么下一次降从1开始,否则为前一次的两倍 官方题解: 您可能是正版Windows ...

  10. 边工作边刷题:70天一遍leetcode: day 82

    Closest Binary Search Tree Value 要点: https://repl.it/CfhL/1 # Definition for a binary tree node. # c ...