找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1951|回复: 4

[研讨] 用鲍威尔法求解最优化问题

[复制链接]
发表于 2013-10-6 16:16:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 高山流水 于 2013-10-6 18:28 编辑

大家好!
很久以前就在想:用LISP写一个求解最优化的通用函数,因为LISP语言本身就比较适合;基于对数学的弱弱了解,写了个粗糙的函数和大家讨论,希望您能多参与这个话题,感谢在先!

  1. ;;(Powell val con arg arg_limit eps)
  2. (defun Powell  (val                  con                    arg
  3.                 arg_limit          eps                    / ss_powell_arg0
  4.                 ss_powell_1dmin          ss_powell_main_function
  5.                 ss_powell_a0          ss_powell_dfm_lst ss_powell_dfm
  6.                 ss_powell_x0          ss_powell_f0            ss_powell_x1
  7.                 ss_powell_f1          ss_powell_x2            ss_powell_f2)
  8.   ;; --------------------------------------------------------;;
  9.   ;; Use Powell method to solve solve optimization problems
  10.   ;;
  11.   ;; Args:
  12.   ;; val -- Expressions calculation function
  13.   ;; con -- Restriction function
  14.   ;; arg -- A string list of the Parameters's name , such as '( "x1" "x2" ...)
  15.   ;; arg_limit -- parameters's limits , like '( (-1e14 1e14) (0 1e14) ...)
  16.   ;; eps -- accuracy
  17.   ;;
  18.   ;; by GSLS(SS) 2013.10.6
  19.   ;;---------------------------------------------------------;;
  20.   (defun ss_powell_1dmin  (x -xm x0 +xm / f0 fa fb -fm +fm)
  21.     ;; One-dimensional search
  22.     ;; This function has not the Powell method .
  23.     ;; How to change it connect with Gradient direction ?
  24.     (set (read x) x0)
  25.     (setq f0 (if (con)
  26.                (val)
  27.                1e99))
  28.     (set (read x) -xm)
  29.     (setq fa (if (con)
  30.                (val)
  31.                1e99))
  32.     (set (read x) (* 0.5 (+ x0 -xm)))
  33.     (setq -fm (if (con)
  34.                 (val)
  35.                 1e99))
  36.     (set (read x) +xm)
  37.     (setq fb (if (con)
  38.                (val)
  39.                1e99))
  40.     (set (read x) (* 0.5 (+ x0 +xm)))
  41.     (setq +fm (if (con)
  42.                 (val)
  43.                 1e99))
  44.     (cond
  45.       ((or (equal x0 -xm eps) (equal x0 +xm eps))
  46.        x0)
  47.       ((< fa -fm f0 +fm fb)
  48.        -xm)
  49.       ((> fa -fm f0 +fm fb)
  50.        +xm)
  51.       ((and (> fa -fm f0) (< f0 +fm fb))
  52.        (ss_powell_1dmin x (*  0.5 (+ x0 -xm)) x0 (* 0.5 (+ x0 +xm))))
  53.       ((and (> fa -fm) (< -fm f0 +fm fb))
  54.        (ss_powell_1dmin x -xm (* 0.5 (+ x0 -xm)) x0))
  55.       ((and (> fb +fm) (> fa -fm f0 +fm))
  56.        (ss_powell_1dmin x x0 (* 0.5 (+ x0 +xm)) +xm))
  57.       ((and (equal x0 -xm (sqrt eps)) (equal x0 +xm (sqrt eps)))
  58.        (/ (+ x0 -xm +xm) 3.))
  59.       ))
  60.   (setq ss_powell_arg0 arg)
  61.   (if arg_limit
  62.     (mapcar
  63.       (function
  64.         (lambda        (x y)
  65.           (cond
  66.             ((or (not y) (apply (function or) y))
  67.              (set (read (strcat x "_limit")) (list -1e14 1e14)))
  68.             ((not (car y))
  69.              (set (read (strcat x "_limit")) (list -1e14 (cadr y))))
  70.             ((not (cadr y))
  71.              (set (read (strcat x "_limit")) (list (car y) 1e14)))
  72.             (t (set (read (strcat x "_limit")) y))
  73.             )))
  74.       arg
  75.       arg_limit)
  76.     (foreach x        arg
  77.       (set (read (strcat x "_limit")) (list -1e14 1e14)))
  78.     ) ;_ x1_limit
  79.   (setq        ss_powell_x0
  80.         (mapcar
  81.            (function
  82.              (lambda (x)
  83.                (*
  84.                 0.5
  85.                 (+
  86.                    (car (eval (read (strcat x "_limit"))))
  87.                    (cadr (eval (read (strcat x "_limit"))))))))
  88.            arg))  
  89.   (defun ss_powell_main_function  (/ ss_powell_i)
  90.     (ss-set arg ss_powell_x0)
  91.     (setq ss_powell_f0
  92.            (if (con)
  93.              (val)
  94.              1e99))
  95.     (setq ss_powell_a0
  96.            (mapcar (function (lambda (x)
  97.                                0.0))
  98.                    arg)
  99.           ss_powell_dfm_lst
  100.            nil
  101.           ss_powell_i 0)
  102.     (mapcar
  103.       (function
  104.         (lambda        (x  /
  105.                 ss_powell_a1_f0      ss_powell_a1_x0
  106.                 ss_powell_a1_l              ss_powell_a1_-xm
  107.                 ss_powell_a1_+xm     ss_powell_a1_ai
  108.                 ss_powell_a1_f1      )
  109.           (setq        ss_powell_a1_f0
  110.                 (if(con)(val)1e99))
  111.           (setq ss_powell_a1_x0 (eval (read x)))
  112.           (setq ss_powell_a1_l (eval (read (strcat x "_limit"))))
  113.           (setq        ss_powell_a1_-xm (car ss_powell_a1_l)
  114.                 ss_powell_a1_+xm (cadr ss_powell_a1_l))
  115.           (setq        ss_powell_a1_ai
  116.                 (- (ss_powell_1dmin
  117.                       x
  118.                       ss_powell_a1_-xm
  119.                       ss_powell_a1_x0
  120.                       ss_powell_a1_+xm)
  121.                     ss_powell_a1_x0))
  122.           (setq ss_powell_a0 (ch-lst ss_powell_a1_ai ss_powell_i ss_powell_a0))
  123.           (ss-set arg
  124.                   (mapcar (function +) ss_powell_x0 ss_powell_a0))
  125.           (setq        ss_powell_a1_f1
  126.                 (if (con)
  127.                    (val)
  128.                    1e99))         
  129.           (setq        ss_powell_dfm_lst
  130.                 (cons (- ss_powell_a1_f0 ss_powell_a1_f1)        ss_powell_dfm_lst))
  131.           (setq ss_powell_i (1+ ss_powell_i))         
  132.           ))
  133.       arg)
  134.     (setq ss_powell_dfm_lst (reverse ss_powell_dfm_lst))
  135.     (setq ss_powell_x1
  136.            (mapcar (function +) ss_powell_x0 ss_powell_a0))
  137.     (setq ss_powell_x2
  138.            (mapcar (function (lambda (x y)
  139.                                (- (* 2. x) y)))
  140.                    ss_powell_x1
  141.                    ss_powell_x0))
  142.     (ss-set arg ss_powell_x1)
  143.     (setq ss_powell_f1
  144.            (if (con)
  145.              (val)
  146.              1e99))
  147.     (ss-set arg ss_powell_x2)
  148.     (setq ss_powell_f2
  149.            (if (con)
  150.              (val)
  151.              1e99)))  
  152.   (ss_powell_main_function)
  153.   (while (not (equal ss_powell_x1 ss_powell_x0 eps))
  154.     (setq ss_powell_dfm (apply (function max) ss_powell_dfm_lst))
  155.     (if
  156.       (or (>= ss_powell_f2 ss_powell_f0)
  157.           (>= (* (+ ss_powell_f0 ss_powell_f2 (* -2. ss_powell_f1))
  158.                 (- ss_powell_f0 ss_powell_f1 ss_powell_dfm))
  159.               (* 0.5
  160.                 ss_powell_dfm
  161.                 (expt (- ss_powell_f0 ss_powell_f2) 2))))
  162.       (progn
  163.        (if (< ss_powell_f1 ss_powell_f2)
  164.         (setq ss_powell_x0 ss_powell_x1)
  165.         (setq ss_powell_x0 ss_powell_x2))
  166.       ;_ (setq ss_powell_dfm_i (vl-sort-i ss_powell_dfm_lst (function >)))   
  167.     )
  168.       (progn;_this is not
  169.         (setq ss_powell_i
  170.                 (car
  171.                   (vl-sort-i ss_powell_dfm_lst (function >))))        
  172.         (setq ss_powell_a0
  173.                 ((lambda(/ i)
  174.                   (setq i -1)
  175.                   (mapcar
  176.                     (function (lambda (y)
  177.                                 (setq i (1+ i))
  178.                                 (if (= i ss_powell_i)
  179.                                   y
  180.                                   (* -2.  y))))                    
  181.                     ss_powell_a0))))
  182.         (setq ss_powell_x0 (mapcar (function +) ss_powell_x0 ss_powell_a0))
  183.         ;_(setq ss_powell_dfm_i (shift(vl-sort-i ss_powell_dfm_lst (function >))))
  184.         )
  185.       ;_(setq ss_powell_x0 ss_powell_x1)
  186.       )
  187.     ;|
  188.     (setq arg (mapcar (function (lambda (i)
  189.                                   (nth i arg)))
  190.                       ss_powell_dfm_i))
  191.     (setq ss_powell_x0 (mapcar (function (lambda (i)
  192.                                   (nth i ss_powell_x0)))
  193.                       ss_powell_dfm_i))|;
  194.     (ss_powell_main_function))
  195.   (ss-set arg ss_powell_x1)
  196.   (setq        ss_powell_f1
  197.         (if (con)
  198.            (val)
  199.            1e99))
  200.   (list (mapcar (function (lambda (x) (eval(read x)))) ss_powell_arg0) ss_powell_f1))

用到的函数
  1. ;;; Used function
  2. (defun ss-set  (ss_set_str_lst ss_set_lst / ss_set_i)
  3.   (setq ss_set_i 0)
  4.   (repeat (length ss_set_lst)
  5.     (set (read (nth ss_set_i ss_set_str_lst))
  6.         (nth ss_set_i ss_set_lst))
  7.     (setq ss_set_i (1+ ss_set_i))))
  8. ;;-----------------------------
  9. (defun ch-lst  (new i lst / j len fst mid)
  10.   (if (/= (type i) (quote list))
  11.     (cond
  12.       ((not (listp lst))
  13.        lst)
  14.       ((minusp i) lst)
  15.       ((> i (setq len (length lst))) lst)
  16.       ((> i (/ len 2))
  17.        (reverse (ch-lst new (1- (- len i)) (reverse lst))))
  18.       (t
  19.        (append
  20.         (progn
  21.            (setq fst nil)
  22.            (repeat (rem i 4)
  23.              (setq fst (cons (car lst) fst)
  24.                    lst (cdr lst)))
  25.            (repeat (/ i 4)
  26.              (setq fst (vl-list* (cadddr lst)
  27.                                 (caddr lst)
  28.                                 (cadr lst)
  29.                                 (car lst)
  30.                                 fst)
  31.                    lst (cddddr lst)))
  32.            (reverse fst))
  33.         (list new)
  34.         (cdr lst))))
  35.     (progn
  36.       (setq j (cadr i)
  37.             i (car i))
  38.       (if j
  39.         (progn
  40.           (setq        mid (nth i lst)
  41.                 mid (ch-lst new j mid))
  42.           (ch-lst mid i lst))
  43.         (ch-lst new i lst)))))
应用例子1:求10(x1+x2-5)^2+(x1-x2)^2的极小点和极小值,理论解: ((2.5 2.5) 0)
  1. (defun val  ()
  2.   ;; 10(x1+x2-5)^2+(x1-x2)^2
  3.   (+ (* 10. (expt (+ x1 x2 -5.) 2)) (expt (- x1 x2) 2)))
  4. (defun con () T)
  5. (setq arg  (list "x1" "x2")
  6.       arg_limit  nil
  7.       eps  1e-6)
  8. (Powell val con arg arg_limit eps);;->((2.5 2.5) 1.32989e-011)
应用例子2:求60-10x1-4x2+x1^2+x2^2-x1x2的极小点和极小值,理论解:((8 6) 8)
  1. (defun val  ()
  2.   ;;60-10x1-4x2+x1^2+x2^2-x1x2
  3.   (+ 60. (* -10. x1) (* -4. x2) (* x1 x1) (* x2 x2) (* -1. x1 x2)))
  4. (defun con () T)
  5. (setq arg  (list "x1" "x2")
  6.       arg_limit  nil
  7.       eps  1e-6)
  8. (Powell val con arg arg_limit eps);;->((8.0 6.0) 8.0)

评分

参与人数 1D豆 +10 贡献 +1 收起 理由
XDSoft + 10 + 1

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 19个

财富等级: 恭喜发财

发表于 2013-10-6 16:43:29 | 显示全部楼层
楼主,是通用的方程式求解吗?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-10-6 16:46:43 | 显示全部楼层
不是的,是多变量最优化求解

点评

能举个专业上应用的例子吗?数学都还给老师了。  详情 回复 发表于 2013-10-6 17:40
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 19个

财富等级: 恭喜发财

发表于 2013-10-6 17:40:43 | 显示全部楼层
高山流水 发表于 2013-10-6 16:46
不是的,是多变量最优化求解

能举个专业上应用的例子吗?数学都还给老师了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-10-6 18:30:32 | 显示全部楼层
1楼有提供2个例子啊
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-12-22 11:24 , Processed in 0.415394 second(s), 46 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表