今天在群里遇到一个问题:
有一10个元素的数组,如何随机分为3部份,每部份分别有4,3,3个元素?
这个问题可以通过随机下标来解决。
下边这个程序可以生成指定个数的随机整型,没有重复。
直接上代码:
;+----------------------------------------------------------------------------------
;|
;;+----------------------------------------------------------------------------------
PRO build_vector,vector,value
IF n_params() lt 2 THEN BEGIN
RETURN
ENDIF
IF N_ELEMENTS(vector) EQ 0 THEN vector=value ELSE vector=[vector,value]
END
;+----------------------------------------------------------------------------------
;|
;;+----------------------------------------------------------------------------------
FUNCTION is_scalar, var
; debug,'V1.0 FH 1998-01-23'
RETURN, ((SIZE(var))[0] EQ 0) AND is_defined(var)
END
;+----------------------------------------------------------------------------------
;|
;;+----------------------------------------------------------------------------------
FUNCTION is_string, var, SCALAR=sc
a = SIZE(var)
n = N_ELEMENTS(a)
IF KEYWORD_SET(sc) THEN $
RETURN, (a[n - 2] EQ 7) AND (a[n-1] EQ 1)
RETURN, a[n - 2] EQ 7
END
;+----------------------------------------------------------------------------------
;|
;;+----------------------------------------------------------------------------------
FUNCTION is_defined, var
; debug,'V1.0 FH 1998-01-20'
a = SIZE(var)
n = N_ELEMENTS(a)
RETURN, a[n - 2] NE 0
END
;+----------------------------------------------------------------------------------
;|
;;+----------------------------------------------------------------------------------
FUNCTION is_element_of, scalar, array, INDEX = ind, COUNT = cnt, $
PARSE = parse, IGNORE_CASE = ign_c
ON_ERROR, 2
IF NOT is_scalar(scalar) THEN MESSAGE, 'Parameter must be a scalar in this context: scalar.'
IF is_string(scalar) THEN BEGIN
lscalar = KEYWORD_SET(ign_c) ? STRUPCASE(scalar) : scalar
larray = KEYWORD_SET(ign_c) ? STRUPCASE(array) : array
IF KEYWORD_SET(parse) THEN BEGIN
ipos = STRPOS(larray, lscalar)
ind = WHERE(ipos EQ 0, cnt)
ENDIF ELSE ind = WHERE(larray EQ lscalar, cnt)
ENDIF ELSE BEGIN
ind = WHERE(array EQ scalar, cnt)
ENDELSE
RETURN, cnt GT 0
END
;+----------------------------------------------------------------------------------
;|
;;+----------------------------------------------------------------------------------
FUNCTION unsorted_uniq,data
search=data
n=N_ELEMENTS(search)
FOR i=0,n-1 DO BEGIN
x=WHERE(data EQ search[i],count_x)
IF N_ELEMENTS(result) GT 0 THEN BEGIN
IF is_element_of (x[0],result) EQ 0 THEN build_vector,result,x[0]
ENDIF ELSE build_vector,result,x[0]
ENDFOR
RETURN,result
END
;+-------------------------------------------------------------------------------------------------
;| array union
;+-------------------------------------------------------------------------------------------------
Function SetUnion, a, b
;
Compile_Opt StrictArr
if N_Elements(a) eq 0 then Return, b ;A union NULL = a
if N_Elements(b) eq 0 then Return, a ;B union NULL = b
Return, Where(Histogram([a,b], OMin = omin)) + omin ; Return combined set
End
;+-------------------------------------------------------------------------------------------------
;| array intersection
;+-------------------------------------------------------------------------------------------------
Function SetIntersection, a, b
;
Compile_Opt StrictArr
minab = Min(a, Max=maxa) > Min(b, Max=maxb) ;Only need intersection of ranges
maxab = maxa < maxb
;
; If either set is empty, or their ranges don't intersect: result = NULL.
if maxab lt minab or maxab lt 0 then Return, -1
r = Where((Histogram(a, Min=minab, Max=maxab) ne 0) and $
(Histogram(b, Min=minab, Max=maxab) ne 0), count)
if count eq 0 then Return, -1 else Return, r + minab
End
;+-------------------------------------------------------------------------------------------------
;| array difference
;+-------------------------------------------------------------------------------------------------
Function SetDifference, a, b
;
Compile_Opt StrictArr
;
; = a and (not b) = elements in A but not in B
mina = Min(a, Max=maxa)
minb = Min(b, Max=maxb)
if (minb gt maxa) or (maxb lt mina) then Return, a ;No intersection...
r = Where((Histogram(a, Min=mina, Max=maxa) ne 0) and $
(Histogram(b, Min=mina, Max=maxa) eq 0), count)
if count eq 0 Then RETURN, -1 else Return, r + mina
End
;+-------------------------------------------------------------------------------------------------
;| 数组取交集,并集,差集
;| 算法来源自IDL Goole讨论组
;| 作者:Huxz
;| The Chinese University of Hong Kong, Institute of Space and Earth Information Science.
;| http://www.iseis.cuhk.edu.hk
;| http://hi.baidu.com/huxz
;| 示例:
;| a = [2,4,6,8]
;| b = [6,1,3,2]
;| FW_Array_UID(a, b, /intersection) = [ 2, 6] ; Common elements, 交集
;| FW_Array_UID(a, b, /union) = [ 1, 2, 3, 4, 6, 8] ; Elements in either set, 并集
;| FW_Array_UID(a, b, /difference) = [ 4, 8] ; Elements in A but not in B, 差集
;| FW_Array_UID(a,[3,5,7]) = -1 ; Null Set
;+-------------------------------------------------------------------------------------------------
Function FW_Array_UID, a, b, union=union, intersection=intersection, difference=difference
;
Compile_Opt StrictArr
if Keyword_Set(union) then begin
Return, SetUnion(a, b)
endif
if Keyword_Set(intersection) then begin
Return, SetIntersection(a, b)
endif
if Keyword_Set(difference) then begin
Return, SetDifference(a, b)
endif
End
;+----------------------------------------------------------------------------------
;| 生成一个整形随机数
;| 输入:num: 整形,需要生成的随机数的个数
;| maxValue, 整形, 随机数的上限值
;| 输出: 返回指定个数的随机数
;| Writen By: Huxz, ISEIS, CUHK
;| 特别鸣谢: IDL_IcgLib from Reimar Bauer
;| 2009-5-15
;;+----------------------------------------------------------------------------------
Function HH_GenerateRandom, num, maxValue
a = Round(RandomU(Seed, num)*maxvalue)
b = a[unsorted_uniq(a)]
c = Indgen(num)
d = FW_Array_UID(c, a, /difference)
e = [b, d]
Return, e
End
;+----------------------------------------------------------------------------------
;| 生成整形随机数
;;+----------------------------------------------------------------------------------
Pro TestRandomu
RandomIndex = HH_GenerateRandom(10, 9)
help, RandomIndex
print, RandomIndex
End