Common Lisp学习笔记(八)

8 Recursion

(defun fact (n)
  (cond ((zerop n) 1)
         (t (* n (fact (- n 1))))))

ex 8.4

(defun laugh (n)
  (cond ((zerop n) nil)
         (t (cons 'ha (laugh (- n 1))))))

ex 8.7

(defun rec-member (entry list)
  (cond ((equal entry (first list)) list)
        (t (rec-member entry (rest list)))))
8.11 recursive templates

double-test tail recursion

(defun func (x)
  (end-test-1 end-value-1)
  (end-test-2 end-value-2)
  (t (func reduced-x)))

single-test tail recursion

(defun func (x)
  (cond (end-test end-value)
        (t (func reduced-x))))

ex 8.27

(defun square-list (list)
  (cond ((null list) nil)
         (t (cons (* (first list) (first list)) (square-list (rest list))))))

ex 8.32

(defun sum-numeric-elements (list)
  (cond ((null list) 0)
        ((numberp (first list)) (+ (first list) (sum-numeric-elements (rest list))))
        (t (sum-numeric-elements (rest list)))))

augmenting recursion

(DEFUN func (x)
  (COND (end-test end-value)
  (T (aug-fun aug-val (func reduced-x)))))

eg,
(defun count-slices (x)
  (cond ((null x) 0)
  (t (+ 1 (count-slices (rest x))))))
8.12 variations on the basic templates

consing

(DEFUN func (N)
  (COND (end-test NIL)
  (T (CONS new-element (func reduced-n)))))

多个变量同时变化

(DEFUN func (N X)
  (COND (end-test end-value)
  (T (func reduced-n reduced-x))))

conditional augmentation

(DEFUN func (X)
  (COND (end-test end-value)
  (aug-test (aug-fun aug-val (func reduced-x))
  (T (func reduced-x))))

eg,
(defun extract-symbols (x)
  (cond ((null x) nil)
  ((symbolp (first x)) (cons (first x) (extract-symbols (rest x))))
  (t (extract-symbols (rest x)))))

multiple recursion, 以fabonacci为代表

(DEFUN func (N)
  (COND (end-test-1 end-value-1)
        (end-test-2 end-value-2)
        (T (combiner (func first-reduced-n) (func second-reduced-n)))))
8.13 trees and car/cdr recursion
(defun func (x)
  (cond (end-test-1 end-value-1)
        (end-test-2 end-value-2)
        (t (combiner (func (car x))
                     (func (cdr x))))))

eg,
(defun find-number (x)
  (cond ((numberp x) x)
        ((atom x) nil)
        (t (or (find-number (car x))
               (find-number (cdr x))))))

ex 8.39

(defun count-cons (tree)
  (cond ((null tree) 1)
        ((atom tree) 1)
        (t (+ (count-cons (car tree)) (count-cons (cdr tree))))))

ex 8.43

(defun flatten (x)
  (cond ((null x) nil)
        ((atom x) (list x))
        (t (append (flatten (car x)) (flatten (cdr x))))))

ex 8.44

(defun tree-depth (x)
  (cond ((null x) 0)
        ((atom x) 0)
        ((setf a (tree-depth (car x)))
         (setf b (tree-depth (cdr x)))
         (cond ((> a b) (+ 1 a))
               (t (+ 1 b))))))
8.14 helping functions
eg,
(defun count-up (n)
  (count-up-recursively 1 n))

(defun count-up-recursively (cnt n)
  (cond ((> cnt n) nil)
        (t (cons cnt (count-up-recursively (+ cnt 1) n)))))

ex 8.60

(setf family
  '((colin nil nil)
    (deirdre nil nil)
    (arthur nil nil)
    (kate nil nil)
    (frank nil nil)
    (linda nil nil)
    (suzanne colin deirdre)
    (bruce arthur kate)
    (charles arthur kate)
    (david arthur kate)
    (ellen arthur kate)
    (george frank linda)
    (hillary frank linda)
    (andre nil nil)
    (tamara bruce suzanne)
    (vincent bruce suzanne)
    (wanda nil nil)
    (ivan george ellen)
    (julie george ellen)
    (marie george ellen)
    (nigel andre hillary)
    (frederick nil tamara)
    (zelda vincent wanda)
    (joshua ivan wanda)
    (quentin nil nil)
    (robert quentin julie)
    (olivia nigel marie)
    (peter nigel marie)
    (erica nil nil)
    (yvette robert zelda)
    (diane peter erica)))

(defun father (x)
  (second (assoc x family)))

(defun mother (x)
  (third (assoc x family)))

(defun parents (x)
  (remove-if #'null (rest (assoc x family))))

(defun children (x)
  (cond ((null x) nil) 
        (t (remove-if-not #'(lambda (entry) (member x (parents entry))) (mapcar #'first family)))))

(defun siblings (x)
  (set-difference (union (children (father x)) (children (mother x))) (list x)))

(defun mapunion (func list)
  (reduce #'union (mapcar func list))) 

(defun grandparents (x)
  (cond ((null (parents x)) nil)
        (t (mapunion #'parents (parents x)))))

(defun cousins (x)
  (mapunion #'children (mapunion #'siblings (parents x))))

(defun descended-from (x y)
  (cond ((null (parents x)) nil)
        ((member y (parents x)) t)
        (t (or (descended-from (father x) y)
               (descended-from (mother x) y)))))

(defun ancestors (x)
  (cond ((null (parents x)) nil)
         (t (union (parents x) (mapunion #'ancestors (parents x))))))

(defun generation-gap (x y)
  (cond ((not (descended-from x y)) nil)
        ((member y (parents x)) 1)
        (y (+ 1 (or (generation-gap (father x) y)
            (generation-gap (mother x) y))))))

8.16 tail recursion

为了提高速度,可以将不是尾部递归的函数改为尾部递归,eg,

;;;version 1
(defun count-slices (x)
  (cond ((null x) 0)
  (t (+ 1 (count-slices (rest x))))))

;;;version 2
(defun tr-count-slices (loaf)
  (tr-cs1 loaf 0)

(defun tr-cs1 (loaf n)
  (cond ((null loaf) n)
         (t (tr-cs1 (rest loaf) (+ n 1)))))

第一个不是尾递归,因为函数在最后调用本身之后还要进行加1的操作,增加一个变量n来进行计数之后,可以将加1的工作提前到调用函数之前,所以变成尾递归

再看一个reverse函数

;;;version 1
(defun my-reverse (x)
  (cond ((null x) nil)
         (t (append (reverse (rest x)) (list (first x))))))

;;;version 2
(defun tr-reverse (x)
  (tr-rev1 x nil))

(defun tr-rev1 (x result)
  (cond ((null x) result)
         (t (tr-rev1 (rest x) (cons (first x) result)))))

不是所有函数都能改写成尾部递归,如multiple recursive的函数就不能

ex 8.61

> (count-up 5)
(1 2 3 4 5)

;;;version 1
(defun count-up (n)
  (count-up-recursively 1 n))

(defun count-up-recursively (cnt n)
  (cond ((> cnt n) nil)
        (t (cons cnt (count-up-recursively (+ cnt 1) n)))))

;;;version 2, tail recursion
(defun count-up (n)
  (recursive-count-up n nil))

(defun recursive-count-up (n result)
  (cond ((zerop n) result)
         (t (recursive-count-up (- n 1) (cons n result)))))

ex 8.62

(defun fact (n)
  (recursive-fact n 1))

(defun recursive-fact (n result)
  (cond ((< n 2) result)
         (t (recursive-fact (- n 1) (* n result)))))
8.18 labels

前面的递归函数需要的辅助函数都是用defun在其他地方定义的,这样的缺陷一个是可能错误调用到辅助函数,还有就是辅助函数由于是单独定义的所以不能访问主要函数的局部变量。一种解决的方法是使用labels函数

(labels ((fn1 args1 body1)
         ...
         (fnn argsn bodyn))
    body)

body即函数主题可以调用任意的局部函数,局部函数也可以调用其他的局部函数,或者主函数的局部变量

(defun count-up (n)
  (labels ((count-up-recursively (cnt)
             (if (> cnt n) nil (cons cnt (count-up-recursively (+ cnt 1))))))
  (count-up-recursively 1)))

ex 8.66 先做简单定义,算术表达式,要不就是一个简单的数,要不就是一个三元list,其中第一个和第三个元素也是算术表达式,第二个元素是+,-,*或者/

(defun arith-eval (x)
  (cond ((numberp x) x)
         (t (funcall (second x) (arith-eval (first x)) (arith-eval (third x))))))

ex 8.67

(defun legalp (x)
  (cond ((numberp x) t)
         ((not (equal (length x) 3)) nil)
         ((not (member (second x) '(+ - * /))) nil)
         (t (and (legalp (first x)) (legalp (third x))))))

转载于:https://www.cnblogs.com/jolin123/p/4491566.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值