革天明 发表于 2013-3-3 09:57:55

如何生成范围在a到b之间的c个随机数,要求数列中连续重复的数字的个数不大于n

如何生成范围在a到b之间的c个随机数,要求数列中连续重复的数字的个数不大于n
举个例子,要生成1-100间的随机数40个,但某人数字连续重复出现的次数小于等于3。
……40 40 40 21 36 15 15 ……这里40重复3次,15重复2次,都是小于等于3

taoyi0727 发表于 2013-3-3 09:57:56

本帖最后由 taoyi0727 于 2020-5-5 16:47 编辑

用G版的改了下(defun f (a b n i / loop lst nn rani temp temp-lst t-get-lst-item-num)
(defun Rani (a b / tmp)
(setq b (1+ b))
    (if (not *Seed*)
      (setq *Seed* (- (setq tmp (getvar "DATE")) (fix tmp)))
    )
    (+ a (fix (*
      (- b a)
      (setq *Seed* (-
                (setq tmp (/ (* *Seed* 1000000000 663608941) 1000000000.0))
                (fix tmp)
               )
      )
       )
   )
    )
)
;;说明:获取表指定项在表中的数量
;;参数:lst:表
;;参数:item:指定项
;;返回:数量
(defun T-get-lst-item-num (lst item)
(apply '+ (mapcar '(lambda (x)
             (if (= item x) 1 0)
            )
      lst
       )
)
)
(setq loop t)
(setq lst nil)
(while loop
(setq nn 0)
(setq temp-lst nil)
(repeat i
   (if (and
      (>= (length lst) i);长度大于重复次数
      (>= (length lst) (1+ nn));长度大于循环次数
   )
    (setq temp-lst (append temp-lst (list (nth nn lst))));获取表前面的重复次数个数
   )
   (setq nn (1+ nn))
)
(setq temp (Rani a b));获取随机数
(if (< (T-get-lst-item-num temp-lst temp) i);小于重复个数
   (progn
    (setq lst (append (list temp) lst))
    (if (= (length lst) n);表长度等于指定长度
   (setq loop nil);退出循环
    )
   )
)
)
lst
)

weiqi 发表于 2013-3-3 12:32:30

不懂写,围观之。

阿然 发表于 2013-3-3 14:59:49


(defun c:tt (/ a b c n i num rndlst rndnumlst)
(vl-load-com)
(defun rnd (rMin rMax);_ Get a random value,Author: aeo
    (vla-eval (vlax-get-acad-object)
              "Randomize"
    );_add randomize by Xran
    (vla-eval (vlax-get-acad-object)
              "ThisDrawing.setVariable \"USERR5\" ,CDbl(Rnd())"
    )
    (+ rMin (* (getvar "userr5") (- rMax rMin)))
)
(if (and (setq a (getint "\n随机数下限:"))
           (setq b (getint "\n随机数上限:"))
           (setq c (getint "\n随机数个数:"))
           (setq n (getint "\n随机数最多重复次数:"))
           (setq i 0)
      )
    (while (< i c)
      (setq d (fix (rnd a b)))
      (if (assoc d rndlst)
        (progn
          (setq num (cdr (assoc d rndlst)))
          (if (< num n)
          (setq rndlst (subst (cons d (1+ num)) (assoc d rndlst) rndlst)
                  i       (1+ i)
                  rndnumlst (append rndnumlst (list d))
          )
          )
        )
        (setq rndlst (append rndlst (list (cons d 1)))
              rndnumlst (append rndnumlst (list d))
              i             (1+ i)
        )
      )
    )
)
rndnumlst
)


xujinhua 发表于 2013-3-3 17:52:10

好像不行
; 错误: Automation 错误。
而且只能整数,

革天明 发表于 2013-3-3 20:21:40

我今天上午已写出一点,目前只有重复次数这项无法搞定,我的不允许出现连续值,不能定义重复次数

Gu_xl 发表于 2013-3-3 20:58:59

本帖最后由 Gu_xl 于 2013-3-3 20:59 编辑

生成范围在a到b之间的n个随机整数,且重复数不大于i

(defun f (a b n i / l r Rani)
(defun Rani (a b / tmp)
    (if      (not *Seed*)
      (setq *Seed* (- (setq tmp (getvar "DATE")) (fix tmp)))
    )
    (+ a
       (fix (* (- b a)
               (setq
               *Seed*      (- (setq
                           tmp (/ (* *Seed* 1000000000 663608941)
                                    1000000000.0
                                 )
                           )
                           (fix tmp)
                        )
               )
            )
       )
    )
)
(cond
    ((or
       (and (> (rem n (1+ (- b a))) 0)
            (< i (1+ (/ n (1+ (- b a)))))
       )
       (and (= (rem n (1+ (- b a))) 0)
            (< i (/ n (1+ (- b a))))
       )
   )
   (prompt "\n没有满足要求的结果")
    )
    ((and (= (rem n (1+ (- b a))) 0)
          (= i (/ n (1+ (- b a))))
   )
   (repeat i
       (setq l (cons a l))
   )
   (while (< a b)
       (setq a (1+ a))
       (repeat i
         (setq l (cons a l))
       )
   )
   (reverse l)
    )
    (t
   (while (< (length l) n)
       (setq r (Rani a b))
       (if (< (- (length l) (length (vl-remove r l))) i)
         (setq l (cons r l))
       )
   )
   (reverse l)
    )
)
)
;;测试: (f 1 100 40 1)

阿然 发表于 2013-3-3 22:14:03

xujinhua 发表于 2013-3-3 17:52 static/image/common/back.gif
好像不行
; 错误: Automation 错误。
而且只能整数,

我在2004下运行没有问题,只能整数是题目要求的,可以是任意小数

jdlfjk 发表于 2013-3-3 23:04:22

本帖最后由 jdlfjk 于 2013-3-4 16:11 编辑

看看
(RandList 1 100 98 2)
(17 36 37 61 63 16 52 4 78 62 6 40 74 63 58 81 77 90 94 94 22 77 53 43 1 22 27 86 42 74 90 53 47 76 51 54 63 13 87 53 23 57 74 60 24 51 37 56 79 11 54 30 24 1 56 27 84 65 12 84 18 58 76 61 29 62 88 47 43 34 69 35 79 73 43 53 83 57 7 55 60 9 80 34 77 81 64 89 74 5 24 94 52 67 55 92 66 7)
;by jdlfjk @mjtd.com
;Random number generation function - based on the linear congruential
;method as presented in Doug Cooper's book Condensed Pascal
(defun RandList      (MinNum MaxNum Num n / co re x y RetList)
(defun randnum (/ modulus multiplier increment random)
    (if      (not seed)
      (setq seed (getvar "DATE"))
    )
    (setq modulus    65536
          multiplier 25173
          increment13849
          seed             (rem (+ (* multiplier seed) increment) modulus)
          random   (/ seed modulus)
          random   (fix (+ MinNum (* (- MaxNum MinNum -1) random)))
    )
)
(setq      co 0
      re 1
)
(while (< co Num)
    (setq y(car RetList)
          co (1+ co)
    )
    (if      (>= re n)
      (while (= (setq x (randnum)) y))
      (if (= (setq x (randnum)) y)
      (setq re (1+ re))
      (setq re 1)
      )
    )
    (setq RetList (cons x RetList))
)
(reverse RetList)
)下面是测试平均数的语句,重复500遍地去获取200个1或2的随机数,允许元素无限重复,最后求得到整数1的个数的平均值

(setq total 0)
(repeat500
(setqco 0)
(foreach one (RANDLIST 1 2 200 200)
    (if(= one 1)
      (setq co (1+ co))
    )
)
(setq total (+ total co))
)
(setq average (/ total 500.0))结果之一:
50148
100.296
说明取的平均数还是趋向平均分布的


革天明 发表于 2013-3-4 08:37:40

本帖最后由 革天明 于 2013-3-4 08:47 编辑

Gu_xl 发表于 2013-3-3 20:58 static/image/common/back.gif
生成范围在a到b之间的n个随机整数,且重复数不大于i
(f 1 3 400 5)
nil
(f 1 10 400 5)
nil
(f 1 50 400 5)
nil
(f 1 75 400 5)
nil
(f 1 80 400 5)
(1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 6 6 6 6 6 7 7 7 7 7 8 8 8 8 8 9 9 9 9 9 10 10 10 10 10 11 11 11 11 11 12 12 12 12 12 13 13 13 13 13 14 14 14 14 14 15 15 15 15 15 16 16 16 16 16 17 17 17 17 17 18 18 18 18 18 19 19 19 19 19 20 20 20 20 20 21 21 21 21 21 22 22 22 22 22 23 23 23 23 23 24 24 24 24 24 25 25 25 25 25 26 26 26 26 26 27 27 27 27 27 28 28 28 28 28 29 29 29 29 29 30 30 30 30 30 31 31 31 31 31 32 32 32 32 32 33 33 33 33 33 34 34 34 34 34 35 35 35 35 35 36 36 36 36 36 37 37 37 37 37 38 38 38 38 38 39 39 39 39 39 40 40 40 40 40 41 41 41 41 41 42 42 42 42 42 43 43 43 43 43 44 44 44 44 44 45 45 45 45 45 46 46 46 46 46 47 47 47 47 47 48 48 48 48 48 49 49 49 49 49 50 50 50 50 50 51 51 51 51 51 52 52 52 52 52 53 53 53 53 53 54 54 54 54 54 55 55 55 55 55 56 56 56 56 56 57 57 57 57 57 58 58 58 58 58 59 59 59 59 59 60 60 60 60 60 61 61 61 61 61 62 62 62 62 62 63 63 63 63 63 64 64 64 64 64 65 65 65 65 65 66 66 66 66 66 67 67 67 67 67 68 68 68 68 68 69 69 69 69 69 70 70 70 70 70 71 71 71 71 71 72 72 72 72 72 73 73 73 73 73 74 74 74 74 74 75 75 75 75 75 76 76 76 76 76 77 77 77 77 77 78 78 78 78 78 79 79 79 79 79 80 80 80 80 80)
应该是要求(>=(/ n i) (1+ (- b a )))
页: [1] 2 3
查看完整版本: 如何生成范围在a到b之间的c个随机数,要求数列中连续重复的数字的个数不大于n