LISP的随机函数的实现

对Autolisp来说,没有生成随机数的函数,一般来说,有如下方法可以产生它:

方法一:用同余函数实现,这是纯LISP的方法。

;;;rand function-some code from Lee Mac,--thanks.
(defun LM:random (Var / x)
  (/ (setq x	4294967296.0
	   seed	(rem (1+ (* 1664525.0
			    (cond (seed)
				  ((getvar var))
			    )
			 )
		     )
		     x
		)
     )
     x
  )
)
(defun Rand (a b var)
  (fix (+ a (* (LM:random var) (- b a -1))))
)

方法二:用系统的相关的变量如cputicks,TDUSRTIMER等实现:

此方法可能会产生一些不是很随机的数。

(defun c:random	()
  (setq seed (getvar "TDUSRTIMER"))
  (setq seed (- seed (fix seed)))
  (rem (* seed 86400) 1)
)

方法三:利用windows系统com中产生随机数。

当前实现Random类基于 Donald E.Knuth 删减随机数生成器算法的修改版本。 有关详细信息,请参阅 D.e。 Knuth。 计算机编程,卷 2 的技术:Seminumerical 算法。 Addison-wesley,Reading,MA,第三个版本,1997年。

(setq rndObj (vlax-create-object "System.Random"))
  (setq x (vlax-invoke rndobj 'nextdouble))
  (setq y (vlax-invoke rndobj 'next))
 
  (defun sysRnd (x y)
    (+ x (* (vlax-invoke rndobj 'nextdouble) (- y x)))
  )

方法四:用vbscript 或者Jscirpt等内部的随机函数产生,然后在lisp用调用脚本语言。

(if
    (or
      (setq wcs (vlax-create-object   "Aec32BitAppServer.AecScriptControl.1"))
      (setq wcs (vlax-create-object "ScriptControl"))
    )
    (vlax-put-property wcs "language" "VBScript")
  )
  (setq str "Randomize
             Function Rand(x,y)\n
                 Rand=x+Rnd*(y-x)\n
             End Function"
  )        
  (vlax-invoke wcs 'addcode str)
 
  (defun wcsRnd(a b)
    (vlax-invoke wcs 'run "rand" a b)
  )

上面的代码经过测试验证,用同余的速度最快,vbs最慢,system.random中间,但同余法的效率并未超过system.random很多,仅仅是几倍的差距。而system.random虽也是伪随机的,但是正确性比同余法高。

一元四次方程的公式解

对于实数系数或复数系数的一元四次方程 \(x^4+bx^3+cx^2+dx+e=0   \) 有以下公式解(证明过程暂时略去,先请大家看看有没有错误)。令:

\( u=1728 b^2 e - 576 b c d + 128 c^3 - 4608 c e + 1728 d^2; \)
\(    v =  48 b d - 16 c^2 - 192 e;     \)
\(  p =\sqrt[3]{\sqrt{u^2 + 4 v^3}+u} ; \)
\( q =\sqrt{\frac{6pb^2+\sqrt[3]{4}p^2-16cp-2\sqrt[3]{2}v}{p}};  \)
\(A=\sqrt{\frac{1}{6}(6b^2-16c-\frac{2\sqrt[3]{2}v}{p}+\sqrt[3]{4}p)};  \)
\(m1=24\sqrt{6}pb^2+8\sqrt[6]{2}\sqrt{3}p^2-64\sqrt{6}cp-8\sqrt[6]{32}\sqrt{3}v ;\)
\(m2=24pqb ;\)
\(n1=2\sqrt[6]{2}\sqrt{3}bp^2+8\sqrt{6}bcp-48\sqrt{6}dp-2\sqrt[6]{32}\sqrt{3}bv ;\)     
\(n2=2\sqrt[3]{4}qb^2+8cpq-2\sqrt[3]{2}qv; \)   
  
原方程的四个根为:

\(x1=\frac{-(m1+m2)+\sqrt{(m1+m2)^2-192pq(n1+n2)}}{96pq}; \)
\(x2=\frac{-(m1+m2)-\sqrt{(m1+m2)^2-192pq(n1+n2)}}{96pq}; \)
\(x3=\frac{(m1-m2)+\sqrt{(m1-m2)^2-192pq(-n1+n2)}}{96pq}; \)
\(x4=\frac{(m1-m2)-\sqrt{(m1-m2)^2-192pq(-n1+n2)}}{96pq}; \)