Here's an example of a random walk that is biased towards the middle of its range and is guaranteed not exceed its bounds.
Hope someone finds it useful, I'm using it for melodies in a generative piece (I'll publish the full patch in a couple of weeks).
Any statisticians want to analyse it further than I have? Anyone have any suggestions for improvements?
http://claudiusmaximus@goto10.org
#N canvas 0 0 781 423 10; #X obj 21 103 f 5; #X obj 184 111 random 10; #X obj 184 137 moses; #X obj 162 194 +; #X obj 21 130 t f f; #X obj 65 225 max -100; #X obj 65 245 t f f; #X floatatom 65 267 5 0 0 0 - - -; #X obj 43 309 t f f; #X floatatom 43 331 5 0 0 0 - - -; #X floatatom 21 371 5 0 0 0 - - -; #X obj 21 26 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1 ; #X obj 162 79 t f b f; #X msg 184 159 -1; #X msg 214 159 1; #X obj 43 288 min 100; #X obj 21 51 metro 100; #X floatatom 79 26 5 0 0 0 - - -; #X obj 21 168 t f f f; #N canvas 0 0 456 412 $0-test-100 0; #X obj 314 172 moses; #X obj 292 229 +; #X obj 151 165 t f f; #X obj 292 114 t f b f; #X msg 314 194 -1; #X msg 344 194 1; #X obj 151 138 f 50; #X obj 314 146 random 99; #X obj 151 223 t f f; #X obj 151 274 + 1; #X obj 151 103 until; #X msg 33 304 normalize 1; #X obj 33 34 t b b b; #X msg 77 280 const 0; #X obj 33 331 s $0-distribution-100; #X obj 151 297 tabwrite $0-distribution-100; #X obj 151 251 tabread $0-distribution-100; #X msg 151 76 100000; #X obj 33 12 inlet; #X connect 0 0 4 0; #X connect 0 1 5 0; #X connect 1 0 6 1; #X connect 2 0 8 0; #X connect 2 1 3 0; #X connect 3 0 1 0; #X connect 3 1 7 0; #X connect 3 2 0 1; #X connect 4 0 1 1; #X connect 5 0 1 1; #X connect 6 0 2 0; #X connect 7 0 0 0; #X connect 8 0 16 0; #X connect 8 1 15 1; #X connect 9 0 15 0; #X connect 10 0 6 0; #X connect 11 0 14 0; #X connect 12 0 11 0; #X connect 12 1 17 0; #X connect 12 2 13 0; #X connect 13 0 14 0; #X connect 16 0 9 0; #X connect 17 0 10 0; #X connect 18 0 12 0; #X restore 476 182 pd $0-test-100; #N canvas 0 0 450 300 (subpatch) 0; #X array $0-distribution-100 100 float 4; #X coords 0 1 99 0 128 100 1; #X restore 474 223 graph; #X obj 476 160 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #N canvas 0 0 450 300 (subpatch) 0; #X array $0-distribution-10 10 float 4; #X coords 0 1 9 0 128 100 1; #X restore 331 223 graph; #X obj 333 161 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #N canvas 0 0 450 300 (subpatch) 0; #X array $0-distribution-1000 1000 float 4; #X coords 0 1 999 0 128 100 1; #X restore 617 223 graph; #X obj 619 160 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #N canvas 0 0 456 412 $0-test-10 0; #X obj 314 172 moses; #X obj 292 229 +; #X obj 151 165 t f f; #X obj 292 114 t f b f; #X msg 314 194 -1; #X msg 344 194 1; #X obj 151 223 t f f; #X obj 151 274 + 1; #X obj 151 103 until; #X msg 33 304 normalize 1; #X obj 33 34 t b b b; #X msg 77 280 const 0; #X msg 151 76 100000; #X obj 33 12 inlet; #X obj 314 145 random 9; #X obj 151 137 f 5; #X obj 151 251 tabread $0-distribution-10; #X obj 151 297 tabwrite $0-distribution-10; #X obj 33 331 s $0-distribution-10; #X connect 0 0 4 0; #X connect 0 1 5 0; #X connect 1 0 15 1; #X connect 2 0 6 0; #X connect 2 1 3 0; #X connect 3 0 1 0; #X connect 3 1 14 0; #X connect 3 2 0 1; #X connect 4 0 1 1; #X connect 5 0 1 1; #X connect 6 0 16 0; #X connect 6 1 17 1; #X connect 7 0 17 0; #X connect 8 0 15 0; #X connect 9 0 18 0; #X connect 10 0 9 0; #X connect 10 1 12 0; #X connect 10 2 11 0; #X connect 11 0 18 0; #X connect 12 0 8 0; #X connect 13 0 10 0; #X connect 14 0 0 0; #X connect 15 0 2 0; #X connect 16 0 7 0; #X restore 333 183 pd $0-test-10; #N canvas 0 0 456 412 $0-test-1000 0; #X obj 314 172 moses; #X obj 292 229 +; #X obj 151 165 t f f; #X obj 292 114 t f b f; #X msg 314 194 -1; #X msg 344 194 1; #X obj 151 223 t f f; #X obj 151 274 + 1; #X obj 151 103 until; #X msg 33 304 normalize 1; #X obj 33 34 t b b b; #X msg 77 280 const 0; #X msg 151 76 100000; #X obj 33 12 inlet; #X obj 151 251 tabread $0-distribution-1000; #X obj 151 297 tabwrite $0-distribution-1000; #X obj 33 331 s $0-distribution-1000; #X obj 314 146 random 999; #X obj 151 138 f 500; #X connect 0 0 4 0; #X connect 0 1 5 0; #X connect 1 0 18 1; #X connect 2 0 6 0; #X connect 2 1 3 0; #X connect 3 0 1 0; #X connect 3 1 17 0; #X connect 3 2 0 1; #X connect 4 0 1 1; #X connect 5 0 1 1; #X connect 6 0 14 0; #X connect 6 1 15 1; #X connect 7 0 15 0; #X connect 8 0 18 0; #X connect 9 0 16 0; #X connect 10 0 9 0; #X connect 10 1 12 0; #X connect 10 2 11 0; #X connect 11 0 16 0; #X connect 12 0 8 0; #X connect 13 0 10 0; #X connect 14 0 7 0; #X connect 17 0 0 0; #X connect 18 0 2 0; #X restore 619 182 pd $0-test-1000; #X text 332 22 self-centering random walk technique; #X text 333 45 probability of decrease decreases as the value decreases ; #X text 333 59 probability of increase decreases as the value increases ; #X text 356 160 N = 10; #X text 498 159 N = 100; #X text 645 159 N = 1000; #X text 330 118 calculated from 100000 steps; #X text 330 100 some value distribution graphs for walks in [0 , N-1] ; #X text 87 331 min ---> 0 as time ---> inf; #X text 110 266 max ---> 10 as time ---> inf; #X text 329 355 self-centering-random-walk.pd (copyleft) 2007-08-10 ; #X text 329 372 Claude Heiland-Allen claudiusmaximus@goto10.org; #X connect 0 0 4 0; #X connect 1 0 2 0; #X connect 2 0 13 0; #X connect 2 1 14 0; #X connect 3 0 0 1; #X connect 4 0 18 0; #X connect 4 1 12 0; #X connect 5 0 6 0; #X connect 6 0 7 0; #X connect 6 1 5 1; #X connect 8 0 9 0; #X connect 8 1 15 1; #X connect 11 0 16 0; #X connect 12 0 3 0; #X connect 12 1 1 0; #X connect 12 2 2 1; #X connect 13 0 3 1; #X connect 14 0 3 1; #X connect 15 0 8 0; #X connect 16 0 0 0; #X connect 17 0 16 1; #X connect 18 0 10 0; #X connect 18 1 15 0; #X connect 18 2 5 0; #X connect 21 0 19 0; #X connect 23 0 26 0; #X connect 25 0 27 0;