CS3343/3341
 Analysis of Algorithms 
Spring 2012
Java Applet for
  Random Distributions:
  Exponential, Uniform, Normal  


Java Applet, Random Distributions

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();
   }
}


Revision date: 2012-01-24. (Please use ISO 8601, the International Standard Date and Time Notation.)