hhc 发表于 2007-1-18 14:45:00

本帖最后由 hhc 于 2012-12-13 14:04 编辑

lisp调用dll,很好

highflybir 发表于 2007-1-18 17:26:00

<p>有个问题:</p><p>希望能调用DLL,生成一个随机排列数组的函数。</p><p>例如有一个数组,元素可能有上百万个,现在要对这个数组的元素随机排列,就像洗牌那样。生成这样一个函数,最后供Vlisp调用。算法上最好能对空间和时间都有照顾!</p><p>以前曾经考虑直接用lisp,但没有成功。下面我引用一段VB代码,只不过是一个特例:</p><p>&nbsp; Dim &nbsp; a(3) &nbsp; As &nbsp; Integer &nbsp; <br/>&nbsp; Private &nbsp; Sub &nbsp; Form_Load() &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a(0) &nbsp; = &nbsp; 3 &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a(1) &nbsp; = &nbsp; 6 &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a(2) &nbsp; = &nbsp; 8 &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a(3) &nbsp; = &nbsp; 9 &nbsp; <br/>&nbsp; End &nbsp; Sub &nbsp; <br/>&nbsp; Private &nbsp; Sub &nbsp; Command1_Click() &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Randomize &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Dim &nbsp; tmp &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Dim &nbsp; tmp_index &nbsp; As &nbsp; Integer &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Dim &nbsp; Lb &nbsp; As &nbsp; Integer, &nbsp; Ub &nbsp; As &nbsp; Integer &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Lb &nbsp; = &nbsp; LBound(a) &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Ub &nbsp; = &nbsp; UBound(a) &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Dim &nbsp; i &nbsp; As &nbsp; Integer &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; For &nbsp; i &nbsp; = &nbsp; Lb &nbsp; To &nbsp; Ub &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tmp_index &nbsp; = &nbsp; Int((Ub &nbsp; - &nbsp; Lb &nbsp; + &nbsp; 1) &nbsp; * &nbsp; Rnd &nbsp; + &nbsp; Lb) &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tmp &nbsp; = &nbsp; a(i) &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a(i) &nbsp; = &nbsp; a(tmp_index) &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a(tmp_index) &nbsp; = &nbsp; tmp &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Next &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; For &nbsp; i &nbsp; = &nbsp; Lb &nbsp; To &nbsp; Ub &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Debug.Print &nbsp; "a(" &nbsp; &amp; &nbsp; i &nbsp; &amp; &nbsp; ")=" &nbsp; &amp; &nbsp; a(i) &nbsp; <br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Next &nbsp; <br/>&nbsp; End &nbsp; Sub</p>

无痕 发表于 2007-1-19 01:28:00

(defun rnd(rMin rMax / e)
   (vla-eval (vlax-get-acad-object) "Randomize : ThisDrawing.setVariable \"USERR5\" ,CDbl((Rnd))" )
   (setq e (+ rMin (* (getvar "userr5")(- rMax rMin))) )
   (if (= 'INT (type rmin)(type rmax))
   (fix e)
   e
   )
)
(defun rndsort (lst / len a lst2)
(repeat (setq len (length lst))
    (while (member (setq a (rnd 0 len)) lst2));;这步算法可优化
    (setq lst2 (cons a lst2))
)
(mapcar '(lambda (x) (nth x lst)) lst2)
);; 测试:
(defun c:tt (/ lst)
(setq lst '(-562969   777 -97   -389-827-197 -850-265
       -933942   444 354   629   -95   612 909   -852
       -267868   428 127   -324845   -834 -203962
       142   561   721 305   347   314   -925 -154-845
       -506575   688 427   -545-752-495 121   -886
       -691364   -758 193   36    324   -762 174   -64
       -182868   698 483   454   -167456 984   -628
       812   861   -901 707   897   -745226 107   943
       -79883   -18 -583327   589   -703 -154-461
       263   -374449 -62   -962-567-764 -860-967
       -139399   -271 772   -157573   -613 -964827
       554
      )
)
(repeat 10
    (print (rndsort lst))
)
)

无痕 发表于 2007-1-19 01:28:00

本帖最后由 作者 于 2007-1-19 2:23:57 编辑

(defun rnd(rMin rMax / e)
   (vla-eval (vlax-get-acad-object) "Randomize : ThisDrawing.setVariable \"USERR5\" ,CDbl((Rnd))" )
   (setq e (+ rMin (* (getvar "userr5")(- rMax rMin))) )
   (if (= 'INT (type rmin)(type rmax))
   (fix e)
   e
   )
)
(defun rndsort (lst / len a lst2)
(repeat (setq len (length lst))
    (while (and
       (member (setq a (rnd 0 len)) lst2);;这步算法可优化
       (or(= 0 a)(member (setq a (1- a)) lst2))
       (or(= a (1- len))(member (setq a (1+ a)) lst2))
    )
      )
    (setq lst2 (cons a lst2))
)
(mapcar '(lambda (x) (nth x lst)) lst2)
)
;; 测试:
(defun c:tt (/ lst)
(setq lst '(-562969   777 -97   -389-827-197 -850-265-933942   444 354   629   -95   612 909   -852
       -267868   428 127   -324845   -834 -203962142   561   721 305   347   314   -925 -154-845
       -506575   688 427   -545-752-495 121   -886-691364   -758 193   36    324   -762 174   -64
       -182868   698 483   454   -167456 984   -628812   861   -901 707   897   -745226 107   943
       -79883   -18 -583327   589   -703 -154-461263   -374449 -62   -962-567-764 -860-967
       -139399   -271 772   -157573   -613 -964827554))
(repeat 10
    (print (rndsort lst))
)
)

无痕 发表于 2007-1-19 03:00:00

这个快一点
(defun rndsort3 (lst / A b I LEN LEN2 LST2 LST3)
;;构造0~(表长-1)整数序列.
(setq len (length lst))
(repeat (setq b len)
    (setq lst2 (cons (setq b (1- b)) lst2))
)
(repeat len
    (setq i    (rnd 0 (length lst2))
   a    (nth i lst2)
          lst3 (cons a lst3)
   lst2 (vl-remove a lst2))
)
(mapcar '(lambda (x) (nth x lst)) lst3)
)

tcsl9621 发表于 2007-1-19 20:53:00

这个帖子抛了块砖,没想到引来了一堆玉。真是不错。这个帖子就是给大家介绍LISP调用DLL文件。这只是个简单引用。但可以编些其他VB函数来供LISP调用。

飞诗(fsxm) 发表于 2007-1-21 18:02:00

试试我这个:

(defun rndsortlst (lst / rndlst)
(repeat (length lst)
    (setq rndlst (cons (rnd) rndlst))
)
(setq rndlst (vl-sort-i rndlst '>))
(mapcar '(lambda (a) (nth a lst)) rndlst)
)

快吗?

龙龙仔 发表于 2007-1-22 12:31:00

<p>16樓(rnd)???</p><p>調用dll還會快嗎?</p><p>;;BY LUCAS&nbsp; (排1千個)</p><p>(defun RND_LAI (/ STR)<br/>&nbsp; (setq STR (rtos (getvar "cputicks") 2 0))<br/>&nbsp; (/ (atoi (substr STR (- (strlen STR) 3))) 10000.0)<br/>)</p><p>;;---------------------------------------------------<br/>(defun RNDSORT5&nbsp;(LEN / A B I LST2 LST3)<br/>&nbsp; (repeat (setq B LEN)<br/>&nbsp;&nbsp;&nbsp; (setq LST2 (cons (setq B (1- B)) LST2))<br/>&nbsp; )<br/>&nbsp; (repeat LEN<br/>&nbsp;&nbsp;&nbsp; (setq I&nbsp;&nbsp;&nbsp; (fix (* LEN (RND_LAI)))<br/>&nbsp;&nbsp; LEN&nbsp; (1- LEN)<br/>&nbsp;&nbsp; A&nbsp;&nbsp;&nbsp; (nth I LST2)<br/>&nbsp;&nbsp; LST3 (cons A LST3)<br/>&nbsp;&nbsp; LST2 (vl-remove A LST2)<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp; )<br/>&nbsp; LST3<br/>)</p><p>(defun C:TT (/ N LST)<br/>&nbsp; (setq&nbsp;N&nbsp;&nbsp; 0<br/>&nbsp;&nbsp; LST NIL<br/>&nbsp; )<br/>&nbsp; (repeat 1000<br/>&nbsp;&nbsp;&nbsp; (setq LST (cons (setq N (1+ N)) LST))<br/>&nbsp; )<br/>&nbsp; (setq STIME (getvar "date"))<br/>&nbsp; (setq LST (mapcar '(lambda (X) (nth X LST)) (RNDSORT5 (length LST))))<br/>&nbsp; (setq ETIME (getvar "date"))<br/>&nbsp; (prompt<br/>&nbsp;&nbsp;&nbsp; (strcat<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "\n程式共耗用時間: "<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (rtos (* 86400.0 (- (- ETIME STIME) (fix (- ETIME STIME))))<br/>&nbsp;&nbsp;&nbsp;&nbsp; 2<br/>&nbsp;&nbsp;&nbsp;&nbsp; 3<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "秒\n"<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp; )<br/>&nbsp; LST<br/>)<br/></p>

highflybir 发表于 2007-1-22 12:50:00

<p>to fsxm:</p><p>的确比无痕的快,谢谢fsxm!但还没明白怎么回事,不知能否把那个rnd函数的源码贴上来呢?</p><p>to 龙版主:</p><p>从你这儿又学了一招!有一个问题是,如果利用cputicks来作随机数,是不是有一定局限性,譬如受浮点影响呢?</p><p></p><p></p>

无痕 发表于 2007-1-23 00:02:00

本帖最后由 作者 于 2007-1-23 0:05:14 编辑

(defun C:TT2 (/ ETIME LST N STIME X)
(setq N   0
LST NIL
)
(repeat 10000
    (setq LST (cons (setq N (1+ N)) LST))
)
(setq STIME (getvar "date"))
(setq LST (mapcar '(lambda (X) (nth X LST)) (rndsi (length lst))))
(setq ETIME (getvar "date"))
(prompt
    (strcat
      "\n程式共耗用時間: "
      (rtos (* 86400.0 (- (- ETIME STIME) (fix (- ETIME STIME))))
   2
   3
      )
      "秒\n"
    )
)
LST
)
程式共耗用時間: 0.469秒
程序也用了cputicks
rndsi和tt2已经打包,下载解压后调入cad可直接运行tt2

页: 1 [2] 3 4
查看完整版本: LISP调用DLL文件生成随机数