CS3343/3341 Analysis of Algorithms Spring 2012 |
Java Applet for Random Distributions: Exponential, Uniform, Normal |
| Java Applet: Random Distributions |
|---|
// DistPlot: plot 3 random distributions: exponential, uniform, normal
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class DistPlot extends Applet implements ActionListener{
boolean nextNormal = true; // used by nextNormalDist
double saveNormal; // used by nextNormalDist
long seed1 = (int)(100000000.0*Math.random()); // nextUniformDist
long seed2 = (int)(100000000.0*Math.random()); // nextUniformDist
long seed3; // nextUniformDist
int[] expC = new int[1000]; // counter for nextExpDist
int[] unifC = new int[500]; // counter for nextUniformDist
int[] normC = new int[500]; // counter for nextNormalDist
double scale; // scale factor for displaying distributions
int xStart = 50, yStart = 150; int xSide = 500;
boolean firstTime = true; // to paint axes the first time through
Button next0, next1, next2, next3; // next buttons
int iter; // number of random points to plot
public void init() {
setBackground(Color.white);
next0 = new Button("1000"); next1 = new Button("10000");
next2 = new Button("100000"); next3 = new Button("1000000");
next0.addActionListener(this); next1.addActionListener(this);
next2.addActionListener(this); next3.addActionListener(this);
add(next0); add(next1); add(next2); add(next3);
}
public void paint(Graphics g) {
for (int i = 0; i <= 300; i += 150) {
g.drawLine(xStart, yStart + i, xStart + xSide, yStart + i);
g.drawLine(xStart + 450, yStart + i - 20, xStart + xSide, yStart + i - 20);
g.drawString("Height: " + iter/500, xStart + 370, yStart + i - 15);
g.drawString("Iterations: " + iter, xStart + 370, 80 + i);
g.drawLine(xStart, yStart + i, xStart, yStart + i - 40);
g.drawLine(xStart + xSide, yStart + i, xStart + xSide, yStart - 40 + i);
}
// for exponential distribution
g.drawString("Graph showing exponential distribution " +
"with average 1", xStart, 50);
for (int i = 0; i <= 5; i++)
g.drawLine(xStart + i*xSide/5, yStart,
xStart + i*xSide/5, yStart + 10);
for (int i = 0; i <= 5; i++)
g.drawString(i*1 + "", xStart + i*xSide/5 - 1, yStart + 23);
// for uniform distribution
g.drawString("Graph showing uniform distribution " +
"from 0 to 1", xStart, 200);
for (int i = 0; i <= 10; i++)
g.drawLine(xStart + i*xSide/10, yStart+150,
xStart + i*xSide/10, yStart + 10 +150);
for (int i = 0; i <= 9; i++)
g.drawString("0." + i + "", xStart + i*xSide/10 - 1,
yStart + 23 +150);
g.drawString("1", xStart + 10*xSide/10 - 1,
yStart + 23 +150);
// for normal distribution
g.drawString("Graph showing normal distribution " +
"with mean 0 and variance 1", xStart, 350);
for (int i = 0; i <= 10; i++)
g.drawLine(xStart + i*xSide/10, yStart+300,
xStart + i*xSide/10, yStart + 10 +300);
for (int i = 0; i <= 10; i++)
g.drawString(i-5 + "", xStart + i*xSide/10 - 1,
yStart + 23 +300);
if (!firstTime) {
for(int dummy = 0; dummy < iter; dummy++) {
int i = (int)(100.0*nextExpDist());
if (i < 1000) expC[i]++;
else expC[999]++;
unifC[(int)(500.0*nextUniformDist())]++;
double r = nextNormalDist();
int j = (int)( 50.0*r) + 250;
if (r < 0.0) j = (int)( 50.0*r) - 1 + 250;
if (j < 0) normC[0]++;
else if (j >= 500) normC[499]++;
else normC[j]++;
}
// exponential distribution
g.setColor(new Color(255, 0, 0)); // red
for (int i = 0; i < 500; i++) {
int temp = (int)(expC[i]/scale);
if (temp >= 1)
g.drawLine(xStart + i, yStart - 1,
xStart + i, yStart - temp);
}
// uniform distribution
for (int i = 0; i < 500; i++) {
int temp = (int)(unifC[i]/scale);
if (temp >= 1)
g.drawLine(xStart + i, yStart - 1 + 150,
xStart + i, yStart - temp + 150);
}
// normal distribution
for (int i = 0; i < 500; i++) {
int temp = (int)(normC[i]/scale);
if (temp >= 1)
g.drawLine(xStart + i, yStart - 1 + 300,
xStart + i, yStart - temp + 300);
}
}
}
// nextUniform: uniformly dist on the interval from 0 to 1
private double nextUniformDist() {
long m = 2147483647;
long k1 = 271828183;
long k2 = 314159269;
seed3 = (k1*seed1 - k2*seed2)%m;
if (seed3 < 0) seed3 += m;
seed1 = seed2; seed2 = seed3;
return (double)seed2 / (double)m;
}
// nextExpDist: exponentially dist with average interarrival time = 1
private double nextExpDist() {
return 1.0*(-Math.log(nextUniformDist()));
}
// nextNormalDist: mean 0 and variance 1
// x1 = sqrt(-2*log(u1))*cos(2*Pi*u2)
// x2 = sqrt(-2*log(u1))*sin(2*Pi*u2)
private double nextNormalDist() {
double u1, u2, x1, x2;
if (nextNormal) {
u1 = nextUniformDist(); u2 = nextUniformDist();
double temp = Math.sqrt(-2.0*Math.log(u1));
x1 = temp*Math.cos(2.0*Math.PI*u2);
x2 = temp*Math.sin(2.0*Math.PI*u2);
saveNormal = x2;
nextNormal = false;
return x1;
}
else {
nextNormal = true;
return saveNormal;
}
}
public void actionPerformed(ActionEvent e) {
firstTime = false;
for (int i = 0; i < 500; i++) {
expC[i] = 0; expC[i + 500] = 0; unifC[i] = 0; normC[i] = 0;
}
if (e.getSource() == next0) { iter = 1000; scale = 0.1; }
else if (e.getSource() == next1) { iter = 10000; scale = 1.0; }
else if (e.getSource() == next2) { iter = 100000; scale = 10.0; }
else if (e.getSource() == next3) { iter = 1000000; scale = 100.0; }
repaint();
}
}
|