Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>GA Babies</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <script type="text/javascript" src="population.js"></script>
    <script>
        var diameter = 960,
            format = d3.format(",d"),
            color = d3.scale.category20c();
        var bubble = d3.layout.pack()
            .sort(null)
            .size([diameter, diameter])
            .padding(1.5);
        $(document).ready(function () {
            var populous = new Population(256);
            var generationCount = 0;
            var svg = d3.select("body").append("svg");
            function drawPopulous() {
                var squareSide = 16;
                for (var j = 0; j < squareSide; j++) {
                    for (var i = 0; i < squareSide; i++) {
                        var circle = svg.attr("width", 1024)
                            .attr("height", 1024)
                            .append("circle")
                            .attr("cx", 30 * (1 + j))
                            .attr("cy", 30 * (1 + i))
                            .attr("r", 10)
                            .style("stroke", "lightgrey")
                            .style("fill", "white");
                        var k = i * (j + i);
                        if (k < populous.population.length) {
                            circle.append("svg:title").text(function (item) {
                                return populous.population[k].geneCode;
                            });
                            var utility = fitness(populous.population[k]);
                            var worst = populous.population[k].geneCode.length;
                            var shade = (255 * utility) / worst;
                            shade = shade.toFixed(0);
                            var colorvalue = "rgb(" + shade + "," + shade + "," + shade + ")";
                            circle.style("fill", colorvalue);
                            if (shade < 50) {
                                StopShizzling();
                                circle.style("stroke", "#00FF88");
                                circle.style("stroke-width", "4");
                            }
                        }
                    }
                }
            }
            var breedthem = function () {
                var genLeap = 100;
                for (var generation = 0; generation < genLeap; generation++) {
                    populous.Breed();
                    $("#gencount").text(generation);
                }
                generationCount += genLeap;
                $("#gencount").text(generationCount);
                // refresh populous grid
                svg.remove();
                svg = d3.select("body").append("svg");
                drawPopulous();
            }
            var intHandler = null;
            function StopShizzling() {
                $("#breedbutton").text("Breed My Preties!");
                clearInterval(intHandler);
                intHandler = null;
            }
            $("#breedbutton").click(function() {
                if (intHandler !== null) {
                    StopShizzling();
                }
                else {
                    populous.initialise();
                    intHandler = setInterval(breedthem, 8);
                    $("#breedbutton").text("STOP!! FOR THE LOVE OF GOD...");
                }
            });
            
            drawPopulous();
        });
    </script>
</head>
<body>
    <div style="padding: 24px;">
        <div>Fitness string:</div>
        <div><input type="text" id="fitness-name" value="JoBloggs"/>
            <button id="breedbutton">Breed My Pretties!</button>
        </div>
        <div style="padding: 24px;">
            Generation: <span id="gencount">0</span>
        </div>
        <div id="population">
        </div>
    </div>
</body>
</html>
 
function Population(agentCount) {
    this.population = new Array();
    var me = this;
    // Initialise population
    this.initialise = function() {
        this.population = new Array();
        for (var index = 0; index < agentCount; index++) {
            var targetFitness = $("#fitness-name").val().toUpperCase();
            var stringLen = targetFitness.length;
            var result = "";
            for (var i = 0; i < stringLen; i++) {
                var digit = Math.round(25 * Math.random());
                var chr = String.fromCharCode(65 + digit);
                result += chr;
            }
            this.population.push(new Baby("" + index, result));
        }
    };
    this.Breed = function () {
        // Sort the populous by fitness utility
        me.population.sort(function(agent1, agent2) {
            return  fitness(agent1) - fitness(agent2);
        });
        // Only breed the first half of the list
        for (var j = 0; j < (me.population.length / 3) ; j++) {
            var item = me.population[j];
            var matePosition = Math.round((Math.random() * (me.population.length / 3)));
            var pairedMate = me.population[matePosition];
            item.crossOverWith(pairedMate);
        }
    };
    this.initialise();
    return this;
}
function hammingDistance(agent, targetFitness) {
    var distance = 0;
    var target = targetFitness.toUpperCase();
    var upperAgent = agent.geneCode.toUpperCase();
    for (var i = 0; i < agent.geneCode.length; i++) {
        distance += upperAgent[i] === target[i] ? 0 : 1;
    }
    return distance;
}
function sumDiff(agent, targetFitness) {
    var distance = 0;
    var target = targetFitness.toUpperCase();
    var upperAgent = agent.geneCode.toUpperCase();
    for (var i = 0; i < agent.geneCode.length; i++) {
        distance += Math.abs(upperAgent[i] - target[i]);
    }
    return distance;
}
function fitness(agent) {
    var targetFitness = $("#fitness-name").val().toUpperCase();
    var distance = hammingDistance(agent, targetFitness);
    //var distance = sumDiff(agent, targetFitness);
    
    return distance;
}
function Baby(name, geneCode) {
    this.geneCode = geneCode;
    this.name = name;
    this.crossOverWith = function(otherParent)
    {
        // Pick a random point in the string
        var endOfString = this.geneCode.length;
        var swapPoint = Math.random() * endOfString;
        // Find same position in other parent
        var myGeneticSubencoding = geneCode.substring(swapPoint, endOfString);
        var myPartnerGeneticSubencoding = otherParent.geneCode.substring(swapPoint, endOfString);
        // Swap the two bits from then on
        this.geneCode = geneCode.substring(0, swapPoint) + myPartnerGeneticSubencoding;
        otherParent.geneCode = geneCode.substring(0, swapPoint) + myGeneticSubencoding;
    };
    this.mutate = function() {
        // This mutates itself. 
        // Pick digit position
        var endOfString = this.geneCode.length;
        var mutatePoint = Math.random() * endOfString;
        // randomise the digit in that position
        this.geneCode[mutatePoint] = Math.random() * 9;
    };
}
function populationView(populous) {
    this.populousViewModel = {
        "name": "population",
        "children" : []
    };
    var me = this;
    populous.population.forEach(function (item) {
        var itemView = {
            "name": item.name,
            "size": "" + fitness(item)
        };
        me.populousViewModel.children.push(itemView);
    });
}
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers