home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
ipl
/
procs
/
weighted.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
4KB
|
88 lines
############################################################################
#
# File: weighted.icn
#
# Subject: Procedure to shuffle list with randomness
#
# Author: Erik Eid
#
# Date: May 23, 1994
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# WeightedShuffle returns the list "sample" with only a portion of the
# elements switched. Examples:
#
# L := WeightedShuffle (X, 100) - returns a fully shuffled list
# L := WeightedShuffle (X, 50) - every other element is eligible to
# be switched
# L := WeightedShuffle (X, 25) - every fourth element is shuffled
# L := WeightedShuffle (X, 0) - nothing is changed
#
# The procedure will fail if the given percentage is not between 0 and
# 100, inclusive, or if it is not a numeric value.
#
############################################################################
procedure WeightedShuffle (sample, percentage)
local lcv, pairs, weight, size, newlist, legal, illegal
numeric(percentage) | fail
(0 <= percentage <= 100) | fail
newlist := copy(sample) # Start with a copy of the
# original list.
size := *newlist
legal := list() # This list will hold which
# indices are valid choices for
# the shuffle, amounting to the
# selected percentage of all
# elements.
# There are two very similar methods used here. I found that using only the
# first one created some odd values for 50 < percentage < 100, so I mirrored
# the technique to create a list of "bad" indices instead of a list of
# "good" indices that the random switch can choose from.
if ((percentage <= 50) | (percentage = 100)) then {
pairs := integer (size * percentage / 100)
# Number of pairs to be switched.
if pairs > 0 then { # Makes sure to avoid division by
# zero- occurs when there is no
# need to shuffle.
weight := integer ((real(size) / pairs) + 0.5)
# Holds increment used in
# selective shuffling, rounded up.
lcv := 1
until lcv > size do {
put (legal, lcv) # These indices may be used in
# the shuffle.
lcv +:= weight
}
}
}
else { # percentage > 50
pairs := integer (size * (100 - percentage) / 100)
# Avoid switching this many pairs.
if pairs > 0 then {
weight := integer (size / pairs) # Increment, rounded down.
illegal := set ([]) # Which indices can't be used?
lcv := 1
until lcv > size do {
illegal ++:= set([lcv]) # Compile the list of invaild
# indices.
lcv +:= weight
}
every lcv := 1 to size do # Whatever isn't bad is good.
if not member (illegal, lcv) then put (legal, lcv)
}
}
every newlist[!legal] :=: newlist[?legal]
# Shuffle elements only from
# legal indices.
return newlist
end