首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一种更有效的多间隔

一种更有效的多间隔
EN

Code Review用户
提问于 2011-04-04 04:59:02
回答 1查看 214关注 0票数 1

来自2.11

练习2.11。顺便说一句,Ben还含糊其辞地评论道:通过测试区间端点的符号,可以将多个区间分解为九种情况,其中一种只需要两次以上的乘法。用本的建议重写这个程序。

我写了以下文章:

代码语言:javascript
复制
(define (negative? . n) (or (= 0 (length n))
                            (and (> 0 (car n)) (apply negative? (cdr n)))))

(define (positive? . n) (or (= 0 (length n))
                            (and (>= (car n) 0) (apply positive? (cdr n)))))

(define (straddles-zero? x) (and (>= 0 (lower-bound x))
                                 (>= (upper-bound x) 0)))

(define (fast-mul-interval x y)
  (let* ((u-x (upper-bound x))
        (u-y (upper-bound y))
        (l-x (lower-bound x))
        (l-y (lower-bound y)))
    (cond 
      ; same sign - max is neg, or min is pos
      ((positive? l-y l-x) (make-interval (* l-x l-y) (* u-x u-y)))
      ((negative? u-y u-x) (make-interval (* u-x u-y) (* l-x l-y)))
      ; x and y have opposite signs
      ((and (positive? l-x) 
            (negative? u-y)) (make-interval (* u-x l-y) (* l-x u-y)))
      ((and (positive? l-y)
            (negative? u-x)) (make-interval (* l-x u-y) (* u-x l-y)))

      ; x straddles zero
      ((straddles-zero? x)
       (if (straddles-zero? y)
           (make-interval (min (* l-x u-y) (* l-y u-x)) 
                          (max (* l-x l-y) (* u-x u-y)))
           (if (negative? u-y)
               (make-interval (* u-x l-y) (* l-x l-y))
               (make-interval (* l-x u-y) (* u-x u-y)))))
      ((straddles-zero? y)
       (if (negative? u-x)
           (make-interval (* u-y l-x) (* l-y l-x))
           (make-interval (* l-y u-x) (* u-y u-x)))))))

你认为如何?

新版本如下:

代码语言:javascript
复制
(define (fast-mul-interval x y)
  (let ((l-x (lower-bound x))
        (u-x (upper-bound x))
        (l-y (lower-bound y))
        (u-y (upper-bound y)))
    (cond ((> l-x 0) 
           ;x > 0
           (cond ((> l-y 0)
                  ;y > 0
                  (make-interval (* l-x l-y) (* u-x u-y))
                  )
                 ((< u-y 0)
                  ;y < 0
                  (make-interval (* u-x l-y) (* l-x u-y))
                  )
                 (else
                  ;y contains 0
                  (make-interval (* u-x l-y) (* u-y u-x))
                  ))
           )
          ((> l-y 0)
           ;y > 0
           (if (< u-x 0)
               ; x < 0
               (make-interval (* u-y l-x) (* l-y u-x))
               ; x contains 0
               (make-interval (* l-x u-y) (* u-x l-y))
               )
           )
          ((< u-x 0)
           ;x < 0
           (if (< u-y 0)
               ; y < 0
               (make-interval (* u-x u-y) (* l-x l-y))
               ; y contains 0
               (make-interval (* u-y u-x) (* l-y u-x))
               )
           )
          ((< u-y 0)
           ;y < 0 and x contains 0
           (make-interval (* u-y u-x) (* l-x u-y))
           )
          (else 
           ;x and y both contain 0
           (let ((p1 (* l-x l-y))
                 (p2 (* l-x u-y))
                 (p3 (* u-x u-y))
                 (p4 (* u-x l-y)))
             (make-interval (min p1 p2 p3 p4) (max p1 p2 p3 p4)))
           ))))
EN

回答 1

Code Review用户

回答已采纳

发布于 2011-04-06 23:30:20

你的逻辑是正确的。

您可以使用let而不是let*,因为一个绑定的值不取决于另一个绑定的值。

因为效率很重要,所以你也可以减少比较的次数。例如,如果u-x是阴性的,那么l-x也是阴性的,不需要测试。因此,negative?positive?straddles-zero?函数是不必要的。相反,只需使用嵌套的ifs:

代码语言:javascript
复制
(if (< u-x 0)
    ; x is in R < 0
    (if (< u-y 0)
        ; y is in R < 0
        ...
        (if (< l-y 0)
            ; y contains 0
            ...
            ; y is in R >= 0
            ... ))
    (if (< l-x 0)
        ; x contains 0
        ...
        ; x is in R >= 0
        ... ))
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/1639

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档