用scheme语言实现SPFA算法(单源最短路)

时间:2022-02-23 07:31:22

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

  这篇文章是我之前程序设计语言课作业中一段代码,用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 &amp&semi; Dijkstra算法&plus;堆优化 &amp&semi; bellman&lowbar;ford &amp&semi; 单源最短路SPFA)

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

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

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

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

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

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

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

  6. &lbrack;ACM&lowbar;图论&rsqb; Domino Effect &lpar;POJ1135 Dijkstra算法 SSSP 单源最短路算法 中等 模板&rpar;

    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单源最短路 &lbrack;kuangbin带你飞&rsqb;专题四 最短路练习 A - Til the Cows Come Home

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

  9. 单源最短路&lowbar;SPFA&lowbar;C&plus;&plus;

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

随机推荐

  1. C&plus;&plus; 系列:继承

    Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...

  2. JavaScript对象状态

    有限状态机(Finite-state machine)是一个非常有用的模型,可以模拟世界上大部分事物. 简单说,它有三个特征: * 状态总数(state)是有限的. * 任一时刻,只处在一种状态之中. ...

  3. php部分---单文件上传的封装类

    <?php $fileinfo=$_FILES["myfile"]; function uploadfile($fileinfo,$allowext=array('jpeg' ...

  4. 【bzoj1046】 HAOI2007—上升序列

    http://www.lydsy.com/JudgeOnline/problem.php?id=1046 (题目链接) 题意 给出一个数列,求数列中长度为L的下标字典序最小的上升子序列. Soluti ...

  5. Hbase常见异常

    1. HBase is able to connect to ZooKeeper but the connection closes immediately hbase(main):001:0> ...

  6. ubuntu 下搭建一个python3的虚拟环境(用于django配合postgresql数据库开发)

     #安装python pip  (在物理环境中安装) sudo apt-get install python-pip       sudo apt-get install python3-pipsud ...

  7. 通过div模拟table

    参考: https://css-tricks.com/complete-guide-table-element/ 不要使用内联样式,但只是为了了解这里是如何去: <section style=& ...

  8. http随笔

    1.什么是http? HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从WWW服务器传输超文本到本地浏览器的传送协议.它可以使浏览器更加高效,使网 ...

  9. cloud server ribbon 自定义策略配置

    虽然ribbon默认为我们提供了多钟负载均衡策略,但有时候我们仍然需要自定义符合自身业务逻辑的规则 使用配置文件的方式:我们只需要在配置文件中添加配置 serviceId.ribbon.NFLoadB ...

  10. MIPI接口LCD屏调试心得(转)

    源: MIPI接口LCD屏调试心得