Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
wenn du erst einen Random-Wert von 1-99.997 abziehst
und danach noch 3x mit dem Rest,
dann hast du vier Zahlen, im Mittel wird eine Zahl bei 50.000 liegen, + 25.000+ 2x 12.500
oder willst du lieber im mittleren Durchschnitt 4x 25.000 erhalten?
eine einfache Möglichkeit dafür: die erste Zufallszahl auf 50.000 begrenzen, die danach auch maximal 50.000,
wenn die ersten drei zusammen kleiner als 50.000 sind, dann musst du von vorne anfangen,
Nachteil oder vielleicht auch Vorteil: keine einzelnen Zahlen > 50.000 dabei
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
public class Test {
private static final int MAX = 100000;
public static void main(String[] args) {
Random random = new Random();
Set<Integer> vals = new TreeSet<Integer>();
while (vals.size() < 3) {
vals.add(random.nextInt(MAX + 1));
}
int start = 0;
for (Integer i : vals) {
Interval interval = new Interval(start, i);
start = i + 1;
System.out.println(interval);
}
Interval end = new Interval(start, MAX);
System.out.println(end);
}
private static class Interval {
private int start;
private int end;
public Interval(int start, int end) {
this.start = start;
this.end = end;
}
public String toString() {
return "[" + start + "," + end + "]";
}
}
}
In bezug auf das letzte hatte ich eine Vermutung, bei der es jetzt ...Indizien gibt, dafür, dass sie wahr ist. Hab' mal "Histogramme" für die verschiedenen Ansätze gezeichnet:
Das ganz links ist das von egat bzw. Schandro: Es wird immer eine zufällige Aufteilung für das verbleibende intervall bestimmt. Man sieht, dass kleine Zahlen unverhältnismäßig viel häufiger auftreten als große - die 1 kommt EXTREM oft vor.
Das mittlere ist mein Ansatz: Das Intervall von 0 bis n wird zufällig in 4 Stücke aufgeteilt. (Ist nur gehackt, nicht aufregen). Die Verteilung ist ziemlich linear... Ob das nun "richtig" ist, weiß ich aber auch nicht :?
Das rechte ist der Alternativvorschlag von SlaterB (auch gehackt - sorry) : Es wird 4x random aufgerufen, und die 4 Einzelwerte als Teile der Summe auf das Intervall umgerechnet. Die Verteilung sieht absolut strange aus - aber mit einem deutlichen "Peak" bei 1/4 des Maximalwertes, was ja nicht unplausibel ist ???:L
Wenn mir mal langweilig ist (ja, NOCH langweiliger, als eben, als ich das geschrieben habe :wink: ) werde ich mir vielleicht mal (für mich selbst) überlegen, wie es "richtig" aussehen müßte. Linear finde ich eigentlich nicht verkehrt, aber begründen kann' ich's nicht, und ich weiß, dass man sich bei solchem Wahrscheinlichkeitskram mit Dingen wie "Intuition" und "Bauchgefühl" ganz übel auf die Fresse legen kann :autsch: (Ich sag' nur http://de.wikipedia.org/wiki/Geburtstagsparadoxon :meld: )
Oder ... sind irgendwelche Stochastik-Freaks hier? Vielleicht kann Andrey ja was dazu sagen? :wink:
Code:
import java.util.*;
import javax.swing.*;
import java.awt.*;
class RandomTest
{
private static final int NUMBER = 300; // ALSO USED AS FRAME SIZE!!!
private static final int RUNS = 50000;
public static void main(String args[])
{
show(test(new RandomComputer0()), 0);
show(test(new RandomComputer1()), 1);
show(test(new RandomComputer2()), 2);
}
private static void show(int a[], int n)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new Histogram(a));
f.setBounds(n*NUMBER,0,NUMBER,NUMBER);
f.setVisible(true);
}
static class Histogram extends JPanel
{
private int min = Integer.MAX_VALUE;
private int max = -1;
private int a[];
public Histogram(int a[])
{
this.a = a;
for (int i=0; i<a.length; i++)
{
min = Math.min(min, a[i]);
max = Math.max(max, a[i]);
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
float sx = (float)getWidth()/a.length;
float sy = (float)getHeight() / (max-min);
for (int i=0; i<a.length; i++)
{
int x = (int)(i * sx);
int y = (int)(a[i] * sy);
g.drawLine(x,getHeight(),x,getHeight()-y);
}
}
}
private static int[] test(RandomComputer rc)
{
int counter[] = new int[NUMBER];
for (int i=0; i<RUNS; i++)
{
int result[] = rc.getThem();
//System.out.println(Arrays.toString(result));
for (int j=0; j<result.length; j++)
{
counter[result[j]]++;
}
if (sum(result) != NUMBER)
{
System.out.println("Sum is "+sum(result)+": "+Arrays.toString(result));
}
}
return counter;
}
private static int sum(int a[])
{
int sum = 0;
for (int i=0; i<a.length; i++)
{
sum += a[i];
}
return sum;
}
interface RandomComputer
{
int[] getThem();
}
static class RandomComputer0 implements RandomComputer
{
public int[] getThem()
{
int zahl = NUMBER;
int result[] = new int[4];
for(int i=0;i<3;++i)
{
int newZahl = (int)(Math.random()*zahl);
result[i] = newZahl;
zahl -= newZahl;
}
result[3] = zahl;
return result;
}
}
static class RandomComputer1 implements RandomComputer
{
float temp[] = new float[3];
public int[] getThem()
{
int result[] = new int[4];
temp[0] = (float)Math.random();
temp[1] = (float)Math.random();
temp[2] = (float)Math.random();
Arrays.sort(temp);
result[0] = (int)(NUMBER * Math.abs(temp[0]-0));
result[1] = (int)(NUMBER * Math.abs(temp[1]-temp[0]));
result[2] = (int)(NUMBER * Math.abs(temp[2]-temp[1]));
result[3] = (int)(NUMBER * Math.abs( 1-temp[2]));
result[3] += (NUMBER - result[0] - result[1] - result[2] - result[3]);
return result;
}
}
static class RandomComputer2 implements RandomComputer
{
public int[] getThem()
{
float r0 = (float)Math.random();
float r1 = (float)Math.random();
float r2 = (float)Math.random();
float r3 = (float)Math.random();
float sum = r0 + r1 + r2 + r3;
int result[] = new int[4];
result[0] = (int)(NUMBER * (r0/sum));
result[1] = (int)(NUMBER * (r1/sum));
result[2] = (int)(NUMBER * (r2/sum));
result[3] = (int)(NUMBER * (r3/sum));
result[3] += (NUMBER - result[0] - result[1] - result[2] - result[3]);
return result;
}
}
}