JavaScript Programs

    To illustrate the implementation of the algorithms presented in this book, three examples are used from easy level, moderate to difficult level. The javaScript language is chosen because it is easy, even for those with very limited coding experience, and no specific software is required beyond internet browser. All three programs are tested using MS Internet Explorer 6.0.

 

Pi Simulation

    The following JavaScript code embedded in html is an implementation of Algorithm 1.1. You can save this file as "Pi.htm". To run the simulation, just double-click the file and will see the simulation result. You can also use other values for the parameter nRuns and see how the result change.

   

     <html> <body>

    <script type="text/javascript">

    var nRuns = 100000;

    var m=0;

    for (iRun=1; iRun<nRuns; iRun++) {

       var x = Math.random();

       var y = Math.random();

       var d = Math.pow((x-0.5),2) + Math.pow((y-0.5),2);

       if(d<0.25) m = m + 1;

    }

    Pi = 4*m/nRuns;

    document.write("Pi = " + Pi);

    </script>

    </body> </html>

 

Adaptive Trial Simulation

 

    The following JavaScript code embedded in html is an implementation of Algorithm 6.5 for adaptive design. Algorithm 2.11 has also been implemented as it is necessary for the adaptive trial simulation. You can save this file as "AdaptiveDesign.htm". To run the simulation, just double-click the file and will see the simulation result.

   

    <html>  <body>

     <script type="text/javascript">

    // Ref: Algorithm 6.5, but on z-scale and without futility stopping.

     document.write("Adaptive Trial Simulation: " + "<br />"+"<br />");

       var z = new Array(), nc = new Array();

       zc = [0, 2.963, 1.969]; // OF-like boundary

       ns = [0, 66, 66]; // ns[0] will not be used.

       var N = 2;

       var delta = 1.0;

       var sigma = 2.5;

       var nRuns = 10000;

       nc[0] = 0;

       for (var k=1;k<=N; k++) nc[k]=nc[k-1]+ns[k];

     var power = 0;

     var power2 =0;

     for (iRun=1; iRun<=nRuns; iRun++) {

        for (var i=1; i<=N; i++) {

        z[i]= delta*Math.sqrt(ns[i]/2)/sigma+ normRan();

        }

        for (var k=1;k<=N; k++) {

           var Tk = 0;

           for (i=1; i<=k; i++) Tk = Tk +Math.sqrt(ns[i]/nc[k])*z[i];

           if (Tk >= zc[k]) {

              power = power +1/nRuns;

              break;

           }

        }

       }

    document.write("Power for the trial design is " + power);

    function normRan() {

       // return random number from N(0,1 ) Ref: Algorithm 2.11.

       var rejection = 1;

       while (rejection == 1) {

          var u1 = 2*Math.random()-1;

          var u2 = 2*Math.random()-1;

          var r2 = u1*u1 + u2*u2;

          if (r2<1) {

             var x1 = u1*Math.sqrt(-2*Math.log(r2)/r2);

             return x1; // just need one.

             rejection = 0;

          }

       }

    }

     </script>

     </body>  </html>

 

Genetic Programming

 

    The following JavaScript code embedded in html is an implementation of Algorithm 13.9. You can save this file as "GP.htm". To run the simulation, just double-click the file and will see the simulation result.

   

    <html> <body>

    <script type="text/javascript">

    //Global variables:

    var genSize =3, popSize=30, treeDepth=3, mcRatio=0.1, carryoverSize=3;

    // 1) Function set;

    var funSet=["sum(xx,yy)", "dif(xx,yy)", "pro(xx,yy)", "quo(xx,yy)", "min(xx,yy)", "max(xx,yy)", "rod(xx)", "pow(xx,yy)", "abs(xx)", "sin(xx)", "cos(xx)", "log(xx)", "tan(xx)", "atn(xx)", "neg(xx)"];

    nFuns=3;

    // 2) Terminal set;

    var termSet=["x", 0.5, 1, 3, "pie()", "exp(1)", "rnd()", "2+5*rnd()"];

    mTerms=2;

    // 3) Population Initialization;

    var parents = new Array();

    var parentFitness = new Array();

    var children = new Array();

    var childFitness = new Array();

    var cFits = new Array();

    // 4) Target function;

    var targetFun="sin(x)";

    var xMin=1;

    var xMax=2;

    var nPoints=50;

    document.write("Teeny Genetic Program Input Parameters: " + "<br/>");

    document.write("Target Function: " + targetFun + " with the evaluation range of (" + xMin + ", " + xMax +") and " + nPoints + " evalution points."+"<br />");

    document.write("Function set: ");

    for (i=0; i<nFuns; i++) document.write(funSet[i]+" ");

    document.write("<br />"+"Terminal set: ");

    for (i=0; i<mTerms; i++) document.write(termSet[i]+" ");

    document.write("<br />"+"Generation size= "+ genSize + ", population size = " + popSize + ", initial tree depth = " + treeDepth + ", mutation proportion = " + mcRatio +", carryover size = " + carryoverSize);

    document.write("<br />");

    // 5) Population initilization;

    for (k=0; k<popSize; k++) {

       myfunTree=new funTree(funSet, nFuns, termSet, mTerms, treeDepth);

       parents[k]=myfunTree.tree;

    }

    fitness(parents, targetFun, popSize, xMin, xMax, nPoints, parentFitness);

    shellSort(parentFitness, parents);

    cFit(parentFitness,cFits);

    for (childId =0; childId<popSize; childId++) {

        var repdut= reproduction(childId, mcRatio, cFits, parents, children, funSet, nFuns, termSet, mTerms);

    }

    fitness(children, targetFun, popSize, xMin, xMax, nPoints, childFitness);

    for (id =0; id<min(5,popSize); id++) {

       if (id==min(5,popSize)-1) document.write("<br/>");

    }

    // 6.1) Reproduction/ evolution;

    document.write("Teeny Genetic Program Outcomes: " + "<br/>");

    for (mm=1; mm<=genSize; mm++) {

       survivor(children, childFitness, popSize, carryoverSize, parents, parentFitness);

       for (childId =0; childId<popSize; childId++) {

       var repdut= reproduction(childId, mcRatio, cFits, parents, children, funSet, nFuns, termSet, mTerms);

       }

        fitness(children, targetFun, popSize, xMin, xMax, nPoints, childFitness);

        document.write("Best of individual in generation " + mm + " is " + parents[0]);

        document.write(" with a fitness of " + parentFitness[0] +"<br />");

     }

    // 6.2) add termination criterio;

    document.write("Best of individual in all generation is " + parents[0]);

    document.write(" with a fitness of " + parentFitness[0] +"<br />");

    //function set include function names with 3 letters and <3 parameters only.

    function sum(a,b){return a+b;}

    function dif(a,b){return a-b;}

    function pro(a,b){return a*b;}

    function quo(a,b){return a/b;}

    function rod(a){return Math.round(a);}

    function rnd(){return Math.random()};

    function sin(x){return Math.sin(x);}

    function cos(x){return Math.cos(x);}

    function log(x){return Math.log(x);}

    function pow(x,a){return Math.pow(x,a);}

    function abs(x){return Math.abs(x);}

    function tan(x){return Math.tan(x);}

    function exp(x){return Math.exp(x);}

    function min(x){return Math.min(x);}

    function max(x){return Math.max(x);}

    function pie(){return Math.PI;}

    function atn(x){return Math.atan(x);}

    function neg(x){return -x;}

    function ran(n){return rod(Math.random()*n+0.5);} //random integer 1 to n;

    function shellSort(myA,myB) {

       // Sorts the array a[0..n-1] into ascending numerical order by Shell sort method.

       // and array b is move simutaneously.

       // The sorting speed is in the order of N^1.25, at least for N<60000.

       // Source: Numerical computation therapies by xxx.

       var j, v, u, inc;

       n=myA.length;

       inc=1; // Determine the starting increment.;

       while (inc <= n) inc *=3, inc++;

       while (inc > 1) {                  // Loop over the partial sorts.

          inc =rod(inc/3);                //original coed is intN(inc/3);

          for (var k=inc+1; k<= n; k++) {      // Outer loop of straight insertion.

             v=myA[k-1];

             u=myB[k-1];

             j=k;

             while (myA[j-inc-1] > v) {      // Inner loop of straight insertion.

                myA[j-1]=myA[j-inc-1];

                myB[j-1]=myB[j-inc-1];

                j -= inc;

                if (j <= inc ) break;

             }

             myA[j-1]=v;

             myB[j-1]=u;

          }

       }

    }

    function getCounts(myTree, me) {

    // return the total counts of me.

     var index0=myTree.indexOf(me);

     if (index0 <0) return 0;

     m=1;

     while (index0>0) {

        index0=myTree.indexOf(me,index0+1);

        if (index0>0) m=m+1;

     }

     return m;

    }

    function nthMe(myStr, me, n) {

    // return the position of nth occurrence of str.;

     var index0=myStr.indexOf(me);

     if (index0 <0) return 0;

     m=1;

     while (m<n) {

     index0=myStr.indexOf(me,index0+1);

     m=m+1;

     }

     return index0;

    }

    function funTree(funSet, nFuns, termSet, mTerms, treeDepth){

     // generate a function string or tree;

     //funSet should have only 1 parameter (xx) or 2 parameters (xx, yy).

     var funcTree=funSet[ran(nFuns)-1];

     for (i=1; i<treeDepth; i++) {

        funcTree=funcTree.replace("xx", funSet[ran(nFuns)-1]);

        funcTree=funcTree.replace("yy", funSet[ran(nFuns)-1]);

       }

     while (funcTree.indexOf("xx")>0) {

        funcTree=funcTree.replace("xx", termSet[ran(mTerms)-1]);

        funcTree=funcTree.replace("yy", termSet[ran(mTerms)-1]);

       }

     while (funcTree.indexOf("rnd()")>0) funcTree=funcTree.replace("rnd()", rnd());

     this.tree=funcTree;

     this.treeDepth=treeDepth;

    }

    function treeSplitor(myStr,index0) {

    // split string into 3 strings: root+funBranch+Brabchs.

     index1=index0;

     index2=index0;

     while (index2<=index1 && index2>0) {

     index1=myStr.indexOf(")",index1+1);

     index2=myStr.indexOf("(",index2+1);

     }

     if (index1<0) index1=myStr.length-1;

     this.root=myStr.substring(0,index0-3);

     this.funBranch=myStr.substring(index0-3,index1+1);

     this.branchs=myStr.substring(index1+1);

     return 1;

    }

    function parentId(cFits, popSize) {

     fitVar = rnd();

     for (var i=0; i<popSize; i++) {

        if (fitVar <= cFits[i]) return i;

     }

     return popSize;

    }

    function gPoint(myTree) {

    // uniformly select any function, return the position of (.

       var nG=ran(getCounts(myTree, "(")-1)+1; // make sure >1.

       return nthMe(myTree, "(", nG);

    }

    function fitness(gpFuns, targetFun, popSize, xMin, xMax, nPoints, fits) {

    // fitness = abs(gpFun-targetFun)) => small value of fitness = better.

     dx = (xMax-xMin)/nPoints;

     for (k=0; k<popSize; k++) {

           fits[k] = 0;

           for (var j=1; j<nPoints; j++) {

              var x = xMin+ j*dx;

              fits[k]=fits[k]+abs(eval(gpFuns[k] + "-" + targetFun))/nPoints;

           }

     }

    }

    function reproduction(childId, mcRatio, cFits, parents, children, funSet, nFuns, termSet, mTerms) {

        var opVar=rnd();

     if (opVar<mcRatio) { // Mutation.

     var parent=parents[parentId(cFits, popSize)];

     var mPoint=gPoint(parent); // mutation point;

     var parentSplitor= new treeSplitor(parent,mPoint);

     var subtreeDepth = rod(0.6*getCounts(parentSplitor.funBranch, "(")); // approaximate

     var myfunTree= new funTree(funSet, nFuns, termSet, mTerms, subtreeDepth);

     children[childId]=parentSplitor.root + myfunTree.tree + parentSplitor.branchs;

     }

       else { // Crossover.

     var mom=parents[parentId(cFits, popSize)];

     var dad=parents[parentId(cFits, popSize)];

     var mPoint=gPoint(mom); // genetic operation point;

     var dPoint=gPoint(dad); // genetic operation point;

     var momSplitor= new treeSplitor(mom,mPoint);

     var dadSplitor= new treeSplitor(dad,dPoint);

     children[childId]=momSplitor.root + dadSplitor.funBranch + momSplitor.branchs;

        }

    }

    function cFit(fitness,cFits) {

    // cumulative probability;

     this.cFits[0]=fitness[0];

     for (k=1; k<popSize; k++) this.cFits[k]=this.cFits[k-1]+fitness[k];

     for (k=0; k<popSize; k++) this.cFits[k]=this.cFits[k]/cFits[popSize-1];

    }

    function survivor(children, childFitness, popSize, carryoverSize, parents, parentFitness) {

     sSize=popSize-carryoverSize;

     shellSort(childFitness, children);

     for (k=0; k<sSize; k++) {

          kc=k+carryoverSize;

          parents[kc]=children[k];

          parentFitness[kc]=childFitness[k];

     }

        shellSort(parentFitness, parents);

    }

    </script>

</body> </html>