Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 1
Default Randomize three variables subject to sum always equal to 1

Hi guys

I need a hand on this one, cuz I have absolutely no clue:

I need a code that randomly selects three real numbers between 0 and
and assigns these to three variables. I defined the variables as w(0)
w(1), w(2). The problem is that the sum has to equal 1! Always! S
that:

w(0) + w(1) + w(2) = 1

Help is very much appreciated!!!

Thanks

Emsfel

--
Message posted from http://www.ExcelForum.com

  #2   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 4,624
Default Randomize three variables subject to sum always equal to 1

One way:

Public Function ThreeRandsAddToOne() As Variant
Dim vTemp As Variant
Application.Volatile
ReDim vTemp(0 To 2)
vTemp(0) = Round(Rnd, 15)
vTemp(1) = Round(Rnd * (1 - vTemp(0)), 15)
vTemp(2) = 1 - (vTemp(0) + vTemp(1))
ThreeRandsAddToOne = Application.Transpose(vTemp)
End Function


Call by array-entering into a vertical range of three cells:

=ThreeRandsAddToOne()



In article ,
emsfeld wrote:

I need a code that randomly selects three real numbers between 0 and 1
and assigns these to three variables. I defined the variables as w(0),
w(1), w(2). The problem is that the sum has to equal 1! Always! So
that:

w(0) + w(1) + w(2) = 1

  #3   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 1
Default Randomize three variables subject to sum always equal to 1

so you have got a solution now. sorry didn't have the time.

- Manges

--
Message posted from http://www.ExcelForum.com

  #4   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 17
Default Randomize three variables subject to sum always equal to 1

Please keep in mind that your solution is NOT complete
random: The first number is (on average) higher than the
other two.

Exchange the indices of your array randomly, I suggest.

Kind regards,
sulprobil
  #5   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 4,624
Default Randomize three variables subject to sum always equal to 1

If order is important, that certainly should be done.

For that matter, note that the third number isn't "completely random" at
any time - it's entirely determined by the first two.


In article ,
"sulprobil" wrote:

Please keep in mind that your solution is NOT complete
random: The first number is (on average) higher than the
other two.

Exchange the indices of your array randomly, I suggest.



  #6   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 4,624
Default Randomize three variables subject to sum always equal to 1

One way:

Public Function ThreeRandsAddToOne() As Variant
Dim vTemp As Variant
Dim dTemp As Double
Dim nRnd As Long
Dim i As Long
Application.Volatile
ReDim vTemp(0 To 2)
vTemp(0) = Round(Rnd, 15)
vTemp(1) = Round(Rnd * (1 - vTemp(0)), 15)
vTemp(2) = 1 - (vTemp(0) + vTemp(1))
For i = UBound(vTemp) To 1 Step -1
nRnd = Int(Rnd * i) + 1
dTemp = vTemp(nRnd)
vTemp(nRnd) = vTemp(i)
vTemp(i) = dTemp
Next i
ThreeRandsAddToOne = Application.Transpose(vTemp)
End Function



In article ,
JE McGimpsey wrote:

If order is important, that certainly should be done.

  #7   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 17
Default Randomize three variables subject to sum always equal to 1

Sorry, no: Both of your programs lead to an average value
of 0.5 for the first variable, I think.

I suggest:
Public Function TRAT() As Variant
Dim vTemp As Variant
Dim i1, i2, i3 As Integer

Application.Volatile
ReDim vTemp(0 To 2)

i1 = Int(Rnd * 3)
i2 = (i1 + 1) Mod 3
i3 = (i1 + 2) Mod 3
vTemp(i1) = Round(Rnd, 15)
vTemp(i2) = Round(Rnd * (1 - vTemp(i1)), 15)
vTemp(i3) = 1 - vTemp(i1) - vTemp(i2)
TRAT = Application.Transpose(vTemp)
End Function

Kind regards,
sulprobil
  #8   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 1
Default Randomize three variables subject to sum always equal to 1

I think the following will work. Actually, you don't need VBA at all fo
this. To get around the problem of negative values for the third number
I'd do the following (this uses the Excel RAND function in th
pseudocode as opposed to the Rnd VBA function).

DesiredSum = 1 (or whatever you want)
r1 = RAND()
r2 = RAND()
r3 = RAND()
SumRand = r1 + r2 + r3
d1 = (r1/SumRand)*DesiredSum
d2 = (r2/SumRand)*DesiredSum
d3 = (r3/SumRand)*DesiredSum

d1, d2, and d3 are the "random" values that now sum to DesiredSum. The
are simply scaled versions of r1, r2, and r3. Note these value
(individually) are not uniformly distributed between 0 and 1. Nor ar
they independent (they are negatively correlated with one another).

Roger Grind

--
Message posted from http://www.ExcelForum.com

  #9   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 17
Default Randomize three variables subject to sum always equal to 1

Yes. That reflects the distribution of Tom's VB program.

Another Worksheet-solution would be:
A1: DesiredSum (1 for example)
B1: =RAND()*$A$1
C1: =RAND()*($A$1-B1)
D1: =$A$1-B1-C1
E1: =INT(RAND()*3)
F1: =OFFSET($B1,0,MOD($E1+COLUMN(), 3))
G1, H1: same as F1

F1:H1 are the - not uniformly distributed, not
independend - random numbers, distribution like my VB
program.

Regards,
sulprobil

  #10   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 274
Default Randomize three variables subject to sum always equal to 1

emsfeld wrote in message ...
Hi guys

I need a hand on this one, cuz I have absolutely no clue:

I need a code that randomly selects three real numbers between 0 and 1
and assigns these to three variables. I defined the variables as w(0),
w(1), w(2). The problem is that the sum has to equal 1! Always! So
that:

w(0) + w(1) + w(2) = 1

Help is very much appreciated!!!

Thanks

Emsfeld



Greetings
As other posters have pointed out, there in more than 1 way to answer
depending on what you are looking for. A very easy way is to imagine
the 3 numbers as being the result of two random cuts, where the random
cuts are uniformly distributed in [0,1]:
something like

cut1 = rnd()
cut2 = rnd()
if cut1 cut2 then
temp = cut1
cut1 = cut2
cut2 = temp
end if
w(0) = cut1
w(1) = cut2 - cut1
w(2) = 1 - cut2

works.

On the other hand, what you are asking for might be the following:
pick a point (x,y,z) at random which satisfies x,y,z = 0 and x + y +
z = 1. Then you are talking about picking a point at random
(presumably uniformly) from an equilateral triangle with sides sqrt(2)
which is situated in 3-D space. A crude algorithm would be to first do
this for a triangle situated in the plane (perhaps by a hit-miss
approach - embed the triangle in a square with sides sqrt(2) and
select points from the square at random (easy) until you get 1 that
hits the triangle, on average 2 or 3 attempts will suffice) and then
apply a linear transformation to get your point in 3-space. I'm sure
that better algorithms exist but this will work and won't be too hard
to code, though not worth the effort if it isn't what you want. If you
want - I can try to code it and might do so tomorrow for fun anyway.

Hope this helps

-John Coleman

---
Message posted from http://www.ExcelForum.com/



  #11   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 274
Default Randomize three variables subject to sum always equal to 1

My last post was way too complicated. I still think that the best
solution to the problem is to generate points (x,y,z) uniformly in the
region detrmined by the constraints, but there is a simpler way to do
so:

Note that the region in question is the graph of the linear function z
= 1-x-y
over the region in the x,y-plane determined by the constraints x,y
=0, x+y <=1.

This later region is exactly one half of the unit square, for which
x+y = 1 is a diagonal. It is clearly enough to pick a point uniformly
distributed in the triangle in the x-y plane and then just evaluate z.
If x and y are independent uniform variables in [0,1], then (x,y) is
uniformly distributed in the unit square. If it is below the diagonal
(if x+y <= 1) - ok. If not, then it is uniformly distributed in the
triangle above the square. But these two triangles are congruent, so
reflecting over the line x+y = 1 puts you in the right triangle (with
the right distribution) after all. Here is code which implemements
this:

Function pickthree() As Variant

'This function returns a variant array consisting of 3
'pseudorandom numbers uniformly distributed over the region
'x,y,z = 0, x+y+z = 1

Dim num1 As Double, num2 As Double, num3 As Double

Randomize
num1 = Rnd()
num2 = Rnd()
If num1 + num2 1 Then 'reflect over line x+y = 1
num1 = 1 - num1
num2 = 1 - num2
End If

'x,y ok now - so let z = 1-x-y and return

num3 = 1 - num1 - num2
pickthree = Array(num1, num2, num3)

End Function

A simple driver to test the function:

Sub testit()
Dim i As Integer, j As Integer
Dim w As Variant
For i = 1 To 20
w = pickthree()
For j = 0 To 2
Range("A1").Offset(i, j).Value = w(j)
Next j
Next i
End Sub

Hope this helps

-John Coleman
  #12   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 9
Default Randomize three variables subject to sum always equal to 1

The problem, or it may be a problem depending on the original poster's need,
is that most of the solutions do not produce 3 RV's with the same
distribution.
Another way to think of the problem is to start with a pie. Generate 3 RV's
where each defines the location of where to make a cut. 0 is at 12 o'clock,
..5 at 6 o'clock, etc. These values would be transformed by defining 3 new
RV's as the size of the slices. By definition, the sum will equal the
whole.

No VB is needed. Just use the following formulas:
Row 1 has the uniformly dist RV's
A1, B1 & C1=rand()
Row 2 is the RV's sorted
A2 = min(A1:C1), B2=large(A1:C1,2), C2=max(A1:C1)
Then the desired RV's would be
A3=B2-A2, B3=C2-B2, C3=1-C2+A2

As with all the solutions, the RV's are not independent.
It's been too many years for me to do the math, but the distribution
appears to be exponential in shape with the highest density at 0
and lowest at 1.
If I could do the math, I also might prove a suspicion that the result is
effectively the same as Tom's.

"John Coleman" wrote in message
om...
My last post was way too complicated. I still think that the best
solution to the problem is to generate points (x,y,z) uniformly in the
region detrmined by the constraints, but there is a simpler way to do
so:

Note that the region in question is the graph of the linear function z
= 1-x-y
over the region in the x,y-plane determined by the constraints x,y
=0, x+y <=1.

This later region is exactly one half of the unit square, for which
x+y = 1 is a diagonal. It is clearly enough to pick a point uniformly
distributed in the triangle in the x-y plane and then just evaluate z.
If x and y are independent uniform variables in [0,1], then (x,y) is
uniformly distributed in the unit square. If it is below the diagonal
(if x+y <= 1) - ok. If not, then it is uniformly distributed in the
triangle above the square. But these two triangles are congruent, so
reflecting over the line x+y = 1 puts you in the right triangle (with
the right distribution) after all. Here is code which implemements
this:

Function pickthree() As Variant

'This function returns a variant array consisting of 3
'pseudorandom numbers uniformly distributed over the region
'x,y,z = 0, x+y+z = 1

Dim num1 As Double, num2 As Double, num3 As Double

Randomize
num1 = Rnd()
num2 = Rnd()
If num1 + num2 1 Then 'reflect over line x+y = 1
num1 = 1 - num1
num2 = 1 - num2
End If

'x,y ok now - so let z = 1-x-y and return

num3 = 1 - num1 - num2
pickthree = Array(num1, num2, num3)

End Function

A simple driver to test the function:

Sub testit()
Dim i As Integer, j As Integer
Dim w As Variant
For i = 1 To 20
w = pickthree()
For j = 0 To 2
Range("A1").Offset(i, j).Value = w(j)
Next j
Next i
End Sub

Hope this helps

-John Coleman



  #13   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 30
Default Randomize three variables subject to sum always equal to 1

On Sat, 04 Sep 2004 02:50:43 GMT, "kcc"
wrote:

The problem, or it may be a problem depending on the original poster's need,
is that most of the solutions do not produce 3 RV's with the same
distribution.


And the one suggested below doesn't do that either.
We don't know if that is a problem or not as the original problem was
to vaguely defined when it comes to what "randomly selects" mean,

Another way to think of the problem is to start with a pie. Generate 3 RV's
where each defines the location of where to make a cut. 0 is at 12 o'clock,
.5 at 6 o'clock, etc. These values would be transformed by defining 3 new
RV's as the size of the slices. By definition, the sum will equal the
whole.

No VB is needed. Just use the following formulas:
Row 1 has the uniformly dist RV's
A1, B1 & C1=rand()
Row 2 is the RV's sorted
A2 = min(A1:C1), B2=large(A1:C1,2), C2=max(A1:C1)
Then the desired RV's would be
A3=B2-A2, B3=C2-B2, C3=1-C2+A2

As with all the solutions, the RV's are not independent.
It's been too many years for me to do the math, but the distribution
appears to be exponential in shape with the highest density at 0
and lowest at 1.
If I could do the math, I also might prove a suspicion that the result is
effectively the same as Tom's.


No, it is not the same as the "divide by the sum" result given by Tom
where the "RV's" do have the same distribution (for what it's worth).
Actually your "A2", "B2", and "C2" variables have the averages of
0.25, 0.5 and 0.75 respectively. That means that your
"A3", "B3" and "C3" variables have the averages of
0.25, 0.25 and 0.5 respectively. Thus the three "RV's" do not have
the same distrubution.

Lars-Åke
  #14   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 9
Default Randomize three variables subject to sum always equal to 1

"Lars-Åke Aspelin" wrote in message
...
On Sat, 04 Sep 2004 02:50:43 GMT, "kcc"
wrote:

The problem, or it may be a problem depending on the original poster's

need,
is that most of the solutions do not produce 3 RV's with the same
distribution.


And the one suggested below doesn't do that either.
We don't know if that is a problem or not as the original problem was
to vaguely defined when it comes to what "randomly selects" mean,

Another way to think of the problem is to start with a pie. Generate 3

RV's
where each defines the location of where to make a cut. 0 is at 12

o'clock,
.5 at 6 o'clock, etc. These values would be transformed by defining 3

new
RV's as the size of the slices. By definition, the sum will equal the
whole.

No VB is needed. Just use the following formulas:
Row 1 has the uniformly dist RV's
A1, B1 & C1=rand()
Row 2 is the RV's sorted
A2 = min(A1:C1), B2=large(A1:C1,2), C2=max(A1:C1)
Then the desired RV's would be
A3=B2-A2, B3=C2-B2, C3=1-C2+A2

As with all the solutions, the RV's are not independent.
It's been too many years for me to do the math, but the distribution
appears to be exponential in shape with the highest density at 0
and lowest at 1.
If I could do the math, I also might prove a suspicion that the result is
effectively the same as Tom's.


No, it is not the same as the "divide by the sum" result given by Tom
where the "RV's" do have the same distribution (for what it's worth).
Actually your "A2", "B2", and "C2" variables have the averages of
0.25, 0.5 and 0.75 respectively. That means that your
"A3", "B3" and "C3" variables have the averages of
0.25, 0.25 and 0.5 respectively. Thus the three "RV's" do not have
the same distrubution.

Lars-Åke


I hate being wrong. The pie analogy was fine, but the implementation
was flawed. I don't know why it didn't occur to me that sorting would
effect the distribution. If I skip the extra step and make
A2==IF(A1=MIN($A1:$C1),LARGE($A1:$C1,2)-A1,IF(A1=LARGE($A1:$C1,2),MAX($A1:$C
1)-A1,1-A1+MIN($A1:$C1)))
and copy to B2 and C2, row 2 will have the distribution I was shooting for.
This time I tested all three RV's rather than one and assume they where the
same. This time, each has a mean of 1/3, as expected.
Ken


Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules

Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
SUMIF Sum a column subject to variables in two columns Steve sivaD Excel Worksheet Functions 4 November 21st 08 01:05 AM
Variables in the subject line of an e-mail hyperlink midol559 Excel Discussion (Misc queries) 0 September 8th 06 04:30 PM
How do I randomize words within a row? K8 Excel Discussion (Misc queries) 2 May 25th 05 09:22 PM
Randomize three variables subject to sum always equal to 1 mangesh_yadav[_49_] Excel Programming 0 August 31st 04 08:00 AM
randomize dallas Excel Programming 11 May 30th 04 08:27 PM


All times are GMT +1. The time now is 11:58 PM.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Copyright ©2004-2025 ExcelBanter.
The comments are property of their posters.
 

About Us

"It's about Microsoft Excel"