【SICP练习】98 练习2.73

本文深入探讨了在Scheme语言中使用数据导向分派实现数学表达式处理的方法,包括加法、乘法和求导等操作的封装与实现,通过自定义操作符和类型标记,展示了如何构造复杂的数据处理流程。

练习2.73

a小题,这是由于Scheme对数字、变量的直接规定,前者会被当作数值类型,后者则会被当作符号类型。因此没必要将这两个谓词添加到数据导向分派中了。如果给数值类型或者符号类型加上一个标志,在get的过程中,又对已知的类型做判断,岂不是在浪费空间和时间。
b小题,我们根据书中已有的范例来完成这道题,也即是第123页最下面到第125页最上面的内容。

(define (install-sum-package) (define (addend s) (car s)) (define (augend s) (cadr s)) (define (make-sum x y) (cons ((=number? x 0) y) ((=number? y 0) x) ((and (number? x) (number? y)) (+ x y)) (else (attach 'add x y)))) (put 'addend 'add addend) (put 'augend 'add augend) (put 'make-sum 'add make-sum) (put 'deriv 'add (lambda (exp var) (make-sum (deriv (addend exp) var) (deriv (augend exp) var)))) 'done)
;Value: install-sum-package
(define (make-sum x y) ((get 'make-sum 'add) x y))
;Value: make-sum
(define (addend sum) ((get 'addend 'add) (contents sum)))
;Value: addend
(define (augend sum) ((get 'augend 'add) (contents sum)))
;Value: augend
(install-sum-package)
;Unbound variable: put
;To continue, call RESTART with an option number:
; (RESTART 8) => Specify a value to use instead of put.
; (RESTART 7) => Define put to a given value.
; (RESTART 6) => Return to read-eval-print level 6.
; (RESTART 5) => Return to read-eval-print level 5.
; (RESTART 4) => Return to read-eval-print level 4.
; (RESTART 3) => Return to read-eval-print level 3.
; (RESTART 2) => Return to read-eval-print level 2.
; (RESTART 1) => Return to read-eval-print level 1.
;Start debugger? (y or n): n

直到写到了这一步,我才发现put没有定义并且不会定义。因此这道题,我曾搁置下来直到通过后面的学习写出了put和get。

(define operation-table (make-table))
(define put (operation-table ‘insert-proc!))
(define get (operation-table ‘lookup-proc))

其中的put中的insert-proc加上一个感叹号,是因为Scheme中的规范——对有破坏性的操作加上”!”。而make-table则在书上第186页及187页有定义,没有学过不要紧,这里就再来用一次传说中的按愿望思维。
b小题中还要求我们写出关于积式的求导过程,然后也要安装到表格之中。

(define (install-product-package) (define (multiplier p) (car p)) (define (multiplicand p) (cadr p)) (define (make-product x y) (cond ((or (=number? x 0) (=number? y 0)) 0) ((=number? x 1) y) ((=number? y 1) x) ((and (number? x) (number? y)) (* x y)) (else (attach-tag ‘mul x y)))) (put ‘multiplier ‘mul multiplier) (put ‘multiplicand ‘mul multiplicand) (put ‘make-product ‘mul make-product) (put ‘deriv ‘mul (lambda (exp var) (make-sum (make-product (multiplier exp) (deriv (multiplicand exp) var)) (make-product (deriv (multiplier exp) var) (multiplicand exp))))) ‘done)
     (define (make-product x y) ((get ‘make-product ‘mul) x y))
     (define (multiplier product) ((get ‘multiplier ‘mul) (contents product)))
       (define (multiplicand product) ((get ‘multiplicand ‘*) (contents product)))

注意之前的attach-tag在这里并不适用,因为其要传入的参数除了一个操作符之外有两个操作对象而不再是一个。

(define (attach-tag type-tag x y) (list type-tag x y))
(define (type-tag datumn) (car datumn))
(define (type-tag datumn) (cdr datumn))

这真是一道漫长的题目哎,c小题参照前面两段代码写起来应该很容易的,如果不知道怎么做乘幂的这个算法,在练习2.56中我们已经遇到过了。
最后一题呢,题目给出了另一种的get形式,但是已经写好的包就不必再加以修改了,因为直接改put即可了。而get中所修改的也只是顺序罢了。因此put的改法也只是改改顺序。

(put ‘make-sum ‘add make-sum)
(put ‘add ‘make-sum make-sum)

前面一个是之前写好的,后面一个是这个小题中改过之后的。



感谢访问,希望对您有所帮助。 欢迎关注或收藏、评论或点赞。


为使本文得到斧正和提问,转载请注明出处:
http://blog.youkuaiyun.com/nomasp


版权声明:本文为 NoMasp柯于旺 原创文章,未经许可严禁转载!欢迎访问我的博客:http://blog.youkuaiyun.com/nomasp

转载于:https://my.oschina.net/nomasp/blog/503274

【电动汽车充电站有序充电调度的分散式优化】基于蒙特卡诺和拉格朗日的电动汽车优化调度(分时电价调度)(Matlab代码实现)内容概要:本文介绍了基于蒙特卡洛和拉格朗日方法的电动汽车充电站有序充电调度优化方案,重点在于采用分散式优化策略应对分时电价机制下的充电需求管理。通过构建数学模型,结合不确定性因素如用户充电行为和电网负荷波动,利用蒙特卡洛模拟生成大量场景,并运用拉格朗日松弛法对复杂问题进行分解求解,从而实现全局最优或近似最优的充电调度计划。该方法有效降低了电网峰值负荷压力,提升了充电站运营效率与经济效益,同时兼顾用户充电便利性。 适合人群:具备一定电力系统、优化算法和Matlab编程基础的高校研究生、科研人员及从事智能电网、电动汽车相关领域的工程技术人员。 使用场景及目标:①应用于电动汽车充电站的日常运营管理,优化充电负荷分布;②服务于城市智能交通系统规划,提升电网与交通系统的协同水平;③作为学术研究案例,用于验证分散式优化算法在复杂能源系统中的有效性。 阅读建议:建议读者结合Matlab代码实现部分,深入理解蒙特卡洛模拟与拉格朗日松弛法的具体实施步骤,重点关注场景生成、约束处理与迭代收敛过程,以便在实际项目中灵活应用与改进。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值