明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: tcsl9621

LISP调用DLL文件生成随机数

    [复制链接]
发表于 2007-1-18 14:45 | 显示全部楼层
本帖最后由 hhc 于 2012-12-13 14:04 编辑

lisp调用dll,很好
发表于 2007-1-18 17:26 | 显示全部楼层

有个问题:

希望能调用DLL,生成一个随机排列数组的函数。

例如有一个数组,元素可能有上百万个,现在要对这个数组的元素随机排列,就像洗牌那样。生成这样一个函数,最后供Vlisp调用。算法上最好能对空间和时间都有照顾!

以前曾经考虑直接用lisp,但没有成功。下面我引用一段VB代码,只不过是一个特例:

  Dim   a(3)   As   Integer  
  Private   Sub   Form_Load()  
          a(0)   =   3  
          a(1)   =   6  
          a(2)   =   8  
          a(3)   =   9  
  End   Sub  
  Private   Sub   Command1_Click()  
           
          Randomize  
           
          Dim   tmp  
          Dim   tmp_index   As   Integer  
          Dim   Lb   As   Integer,   Ub   As   Integer  
          Lb   =   LBound(a)  
          Ub   =   UBound(a)  
           
          Dim   i   As   Integer  
          For   i   =   Lb   To   Ub  
                  tmp_index   =   Int((Ub   -   Lb   +   1)   *   Rnd   +   Lb)  
                  tmp   =   a(i)  
                  a(i)   =   a(tmp_index)  
                  a(tmp_index)   =   tmp  
          Next  
          For   i   =   Lb   To   Ub  
                  Debug.Print   "a("   &   i   &   ")="   &   a(i)  
          Next  
  End   Sub

发表于 2007-1-19 01:28 | 显示全部楼层
  1. (defun rnd(rMin rMax / e)
  2.    (vla-eval (vlax-get-acad-object) "Randomize : ThisDrawing.setVariable "USERR5" ,CDbl((Rnd))" )
  3.    (setq e (+ rMin (* (getvar "userr5")(- rMax rMin))) )
  4.    (if (= 'INT (type rmin)(type rmax))
  5.      (fix e)
  6.      e
  7.    )
  8. )
  9. (defun rndsort (lst / len a lst2)
  10.   (repeat (setq len (length lst))
  11.     (while (member (setq a (rnd 0 len)) lst2));;这步算法可优化
  12.     (setq lst2 (cons a lst2))
  13.   )
  14.   (mapcar '(lambda (x) (nth x lst)) lst2)
  15. )
  1. ;; 测试:
  2. (defun c:tt (/ lst)
  3.   (setq lst '(-562  969   777 -97   -389  -827  -197 -850  -265
  4.        -933  942   444 354   629   -95   612 909   -852
  5.        -267  868   428 127   -324  845   -834 -203  962
  6.        142   561   721 305   347   314   -925 -154  -845
  7.        -506  575   688 427   -545  -752  -495 121   -886
  8.        -691  364   -758 193   36    324   -762 174   -64
  9.        -182  868   698 483   454   -167  456 984   -628
  10.        812   861   -901 707   897   -745  226 107   943
  11.        -798  83   -18 -583  327   589   -703 -154  -461
  12.        263   -374  449 -62   -962  -567  -764 -860  -967
  13.        -139  399   -271 772   -157  573   -613 -964  827
  14.        554
  15.       )
  16.   )
  17.   (repeat 10
  18.     (print (rndsort lst))
  19.   )
  20. )
发表于 2007-1-19 01:28 | 显示全部楼层
本帖最后由 作者 于 2007-1-19 2:23:57 编辑

  1. (defun rnd(rMin rMax / e)
  2.    (vla-eval (vlax-get-acad-object) "Randomize : ThisDrawing.setVariable "USERR5" ,CDbl((Rnd))" )
  3.    (setq e (+ rMin (* (getvar "userr5")(- rMax rMin))) )
  4.    (if (= 'INT (type rmin)(type rmax))
  5.      (fix e)
  6.      e
  7.    )
  8. )
  9. (defun rndsort (lst / len a lst2)
  10.   (repeat (setq len (length lst))
  11.     (while (and
  12.        (member (setq a (rnd 0 len)) lst2);;这步算法可优化
  13.        (or(= 0 a)(member (setq a (1- a)) lst2))
  14.        (or(= a (1- len))(member (setq a (1+ a)) lst2))
  15.     )
  16.       )
  17.     (setq lst2 (cons a lst2))
  18.   )
  19.   (mapcar '(lambda (x) (nth x lst)) lst2)
  20. )
  1. ;; 测试:
  2. (defun c:tt (/ lst)
  3.   (setq lst '(-562  969   777 -97   -389  -827  -197 -850  -265  -933  942   444 354   629   -95   612 909   -852
  4.        -267  868   428 127   -324  845   -834 -203  962  142   561   721 305   347   314   -925 -154  -845
  5.        -506  575   688 427   -545  -752  -495 121   -886  -691  364   -758 193   36    324   -762 174   -64
  6.        -182  868   698 483   454   -167  456 984   -628  812   861   -901 707   897   -745  226 107   943
  7.        -798  83   -18 -583  327   589   -703 -154  -461  263   -374  449 -62   -962  -567  -764 -860  -967
  8.        -139  399   -271 772   -157  573   -613 -964  827  554))
  9.   (repeat 10
  10.     (print (rndsort lst))
  11.   )
  12. )
发表于 2007-1-19 03:00 | 显示全部楼层
这个快一点
  1. (defun rndsort3 (lst / A b I LEN LEN2 LST2 LST3)
  2.   ;;构造0~(表长-1)整数序列.
  3.   (setq len (length lst))
  4.   (repeat (setq b len)
  5.     (setq lst2 (cons (setq b (1- b)) lst2))
  6.   )
  7.   (repeat len
  8.     (setq i    (rnd 0 (length lst2))
  9.    a    (nth i lst2)
  10.           lst3 (cons a lst3)
  11.    lst2 (vl-remove a lst2))
  12.   )
  13.   (mapcar '(lambda (x) (nth x lst)) lst3)
  14. )

评分

参与人数 1威望 +1 明经币 +2 金钱 +20 贡献 +5 激情 +5 收起 理由
mccad + 1 + 2 + 20 + 5 + 5 【精华】好程序

查看全部评分

 楼主| 发表于 2007-1-19 20:53 | 显示全部楼层
这个帖子抛了块砖,没想到引来了一堆玉。真是不错。这个帖子就是给大家介绍LISP调用DLL文件。这只是个简单引用。但可以编些其他VB函数来供LISP调用。
发表于 2007-1-21 18:02 | 显示全部楼层
试试我这个:
  1. (defun rndsortlst (lst / rndlst)
  2.   (repeat (length lst)
  3.     (setq rndlst (cons (rnd) rndlst))
  4.   )
  5.   (setq rndlst (vl-sort-i rndlst '>))
  6.   (mapcar '(lambda (a) (nth a lst)) rndlst)
  7. )
快吗?
发表于 2007-1-22 12:31 | 显示全部楼层

16樓(rnd)???

調用dll還會快嗎?

;;BY LUCAS  (排1千個)

(defun RND_LAI (/ STR)
  (setq STR (rtos (getvar "cputicks") 2 0))
  (/ (atoi (substr STR (- (strlen STR) 3))) 10000.0)
)

;;---------------------------------------------------
(defun RNDSORT5 (LEN / A B I LST2 LST3)
  (repeat (setq B LEN)
    (setq LST2 (cons (setq B (1- B)) LST2))
  )
  (repeat LEN
    (setq I    (fix (* LEN (RND_LAI)))
   LEN  (1- LEN)
   A    (nth I LST2)
   LST3 (cons A LST3)
   LST2 (vl-remove A LST2)
    )
  )
  LST3
)

(defun C:TT (/ N LST)
  (setq N   0
   LST NIL
  )
  (repeat 1000
    (setq LST (cons (setq N (1+ N)) LST))
  )
  (setq STIME (getvar "date"))
  (setq LST (mapcar '(lambda (X) (nth X LST)) (RNDSORT5 (length LST))))
  (setq ETIME (getvar "date"))
  (prompt
    (strcat
      "\n程式共耗用時間: "
      (rtos (* 86400.0 (- (- ETIME STIME) (fix (- ETIME STIME))))
     2
     3
      )
      "秒\n"
    )
  )
  LST
)

发表于 2007-1-22 12:50 | 显示全部楼层

to fsxm:

的确比无痕的快,谢谢fsxm!但还没明白怎么回事,不知能否把那个rnd函数的源码贴上来呢?

to 龙版主:

从你这儿又学了一招!有一个问题是,如果利用cputicks来作随机数,是不是有一定局限性,譬如受浮点影响呢?

发表于 2007-1-23 00:02 | 显示全部楼层
本帖最后由 作者 于 2007-1-23 0:05:14 编辑

  1. (defun C:TT2 (/ ETIME LST N STIME X)
  2.   (setq N   0
  3. LST NIL
  4.   )
  5.   (repeat 10000
  6.     (setq LST (cons (setq N (1+ N)) LST))
  7.   )
  8.   (setq STIME (getvar "date"))
  9.   (setq LST (mapcar '(lambda (X) (nth X LST)) (rndsi (length lst))))
  10.   (setq ETIME (getvar "date"))
  11.   (prompt
  12.     (strcat
  13.       "\n程式共耗用時間: "
  14.       (rtos (* 86400.0 (- (- ETIME STIME) (fix (- ETIME STIME))))
  15.      2
  16.      3
  17.       )
  18.       "秒\n"
  19.     )
  20.   )
  21.   LST
  22. )
程式共耗用時間: 0.469秒
程序也用了cputicks
rndsi和tt2已经打包,下载解压后调入cad可直接运行tt2

回复 支持 1 反对 0

使用道具 举报

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

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-20 15:44 , Processed in 0.458871 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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