How to perform a random split on a value

40 Views Asked by At

I have 30 dollars, randomly split it into 3 parts, and send it to persons A, B, and C.

After playing an infinite number of games, the expected payoff of each person can be:

Case A

person A: 15 person B: 7.5 person C: 7.5

Or

Case B

person A: 10 person B: 10 person C: 10

I think it depends on how you randomly split the values into 3 parts

Case A

person A: randomly get a number from (0-15)
person B: randomly get a number from (15 - the money that person A got)
person C: 15 - the money that person A + person B got

In the above case, it is no longer a fair game, because the first person will always have a larger range of chances to get a higher number

Case B

However, I have no idea how to design a fair random split.

1

There are 1 best solutions below

0
On

It would be simple if you see it as cutting a circle. How to cut a circle to 3 pieces randomly? Just choose 3 points randomly! Then the three pieces should have equal expectation of length.

Due to symmetry, we can fix one point at zero, so we just need to choose the other two points. If the problem is continuous, that should be it. We sort the points and find their differences. For discrete problem, we need to make a little adjustment, since we should "round" the result to nearest integer. We could use another random number to do that.

E.g, for n=30, in C++, we can choose the numbers this way:

#include <bits/stdc++.h>
using namespace std;
int main(){
    srand(time(0));
    int n=30;
    int cnt=0,A=0,B=0,C=0;
    for(;cnt<10000;++cnt){
        int t1=rand()%n+rand()%2;
        int t2=rand()%n+rand()%2;
        A+=min(t1,t2);
        B+=abs(t1-t2);
        C+=n-max(t1,t2);
    }
    cout<<"A="<<double(A)/cnt<<",B="<<double(B)/cnt<<",C="<<double(C)/cnt;
    return 0;
}

possible output:

A=9.9646,B=9.9869,C=10.0485

Or we could just choose $n$ points, since adding one more point doesn't make much difference.

#include <bits/stdc++.h>
using namespace std;
const int N=3;
int n=30;
int main(){
    srand(time(0));
    int points[N];
    int len[N];
    for(int i=0;i<N;++i){
        len[i]=0;
    }
    int cnt=0;
    for(;cnt<10000;++cnt){
        for(int i=0;i<N;++i){
            points[i]=rand()%n;
        }
        sort(points,points+N);
        int j=rand()%N; // need to choose starting point randomly, 
                        // because the points are distributed in [0,n-1],
                        // if j starts at 0, there will be discrepancy,
                        // since there is always a "gap" between n-1 and 0.
        for(int i=1;i<N;++i,++j) len[j%N]+=points[i]-points[i-1];
        len[j%N]+=points[0]+n-points[N-1];
    }
    for(int i=0;i<N;++i) cout<<(double)len[i]/cnt<<",";
    cout<<endl;
    return 0;
}

possible output:

10.0401,9.9872,9.9727,