Reputation: 9
I have written these few lines to make a random image with given size & n is number of black pixel I want.
I see that when I run with 512 in size and 511 * 511 for pixel number, image should be black but it's only partial. I think it's because he can pick two times the same x or y ?
How can I modify this to add verification if j.(x).(y)
is used or not ?
let rdm_img2 size n =
let img = Array.make_matrix size size Blanc in (
snd(forloop((0, img),
n,
(function(i, j) ->
let x, y = pickRdmxy(size) in
match x,y with
j.(x).(y) = Noir -> pickRdmxy size;
j.(x).(y) = Blanc -> j.(x).(y) <- Noir;
(i,j)
)
)))
;;
and forloop
is this lines :
let rec forloop(r, n, next : 'a * int* ('a -> 'a)) : 'a =
if n = 0 then r
else forloop (next(r), n-1, next)
;;
and pickRdmxy
just return a random int between 0
and size.
Upvotes: 0
Views: 59
Reputation: 18902
Your code is not valid and cannot compile since
match x,y with
j.(x).(y) = Noir -> pickRdmxy size;
j.(x).(y) = Blanc ->
is a syntax error. I imagine that you meant
match j.(x).(y) with
| Noir -> pickRdmxy size
| Blanc -> ...
Moreover, you are not using the arguments of your function, thus a normal for loop is clearer:
let img = Array.make_matrix size size Blanc in (
for _ = 1 to n do
let x, y = pickRdmxy(size) in
match j.(x).(y) with
| Noir -> ()
| Blanc -> j.(x).(y) <- Noir
done
Going back to your question, you are sampling with repetition, thus with a high probability, you will get collisions and will not sample all pixels after sampling exactly the number of pixels in your image.
If you want to sample without repetition, you need to change algorithms. One way to do it is to compute a permutation of all indices, with a Knuth's shuffle for instance
let shuffle a =
let a = Array.copy a in
for i = Array.length a - 1 downto 0 do
let r = Random.int (i+1) in
let tmp = a.(r) in
a.(r) <- a.(i);
a.(i) <- tmp
done;
a
let sample_without_repetition n f sample_set =
let permuted_sample_set = shuffle sample_set in
for i = 0 to n-1 do f permuted_sample_set.(i) done
Upvotes: 1