Skip to content

Commit

Permalink
TSP Server/Client using Socket.io
Browse files Browse the repository at this point in the history
  • Loading branch information
ajlopez committed Sep 9, 2012
1 parent 1aca443 commit 8a16b6a
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 129 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
node_modules
1 change: 1 addition & 0 deletions .npmignore
@@ -0,0 +1 @@
/samples
2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -12,5 +12,7 @@
, "dependencies": {
}
, "devDependencies": {
"socket.io",
"express"
}
}
8 changes: 4 additions & 4 deletions samples/tsp/tsp.js
@@ -1,5 +1,5 @@

var tpl = (function() {
var tsp = (function() {
// http://www.merlyn.demon.co.uk/js-shufl.htm#FnB

function shuffle(values)
Expand Down Expand Up @@ -89,8 +89,8 @@ var tpl = (function() {
var pos1 = Math.floor(Math.random() * l);
var pos2 = (pos1 + 1) % l;

/* if (Math.random() >= 0.8)
pos2 = Math.floor(Math.random() * l);*/
if (Math.random() >= 0.8)
pos2 = Math.floor(Math.random() * l);

var value = values[pos1];
values[pos1] = values[pos2];
Expand Down Expand Up @@ -119,6 +119,6 @@ var tpl = (function() {
}());

if (typeof(window) === 'undefined') {
module.exports = tpl;
module.exports = tsp;
}

136 changes: 11 additions & 125 deletions samples/tsphtml/index.html
Expand Up @@ -2,120 +2,16 @@
<head>
<title>Travelling Salesman Problem Sample</title>
<script src="../../lib/simplega.js" language="javascript"></script>
<script src="../tsp/tsp.js" language="javascript"></script>
</head>
<body>
<h1>Travelling Salesman Problem Sample</h1>

<input type="button" value="Relaunch" onclick="relaunch()">

<canvas id="canvas" width="500" height="400">
<canvas id="canvas" width="600" height="500">
</canvas>

<script language="javascript">

// http://www.merlyn.demon.co.uk/js-shufl.htm#FnB

function shuffle(values)
{
var l = values.length;

for (var k = l, j; k-- > 0; )
{
var value = values[k];
j = Math.floor(Math.random() * l);
values[k] = values[j];
values[j] = value;
}

return values;
}

function getPoints(m, n)
{
var points = [];

for (var k = 0; k < m; k++)
for (var j = 0; j < n; j++)
points.push({ x: k, y: j });

return points;
}

function getValues(n)
{
var values = new Array(n);

for (var k = 0; k < n; k++)
values[k] = k;

return values;
}

function Genotype(points, maxlength, values)
{
var n = points.length;
var value = 0;

if (!values) {
values = getValues(n);
shuffle(values);
}

this.evaluate = function() {
if (value)
return value;

value = maxlength;

var x = points[values[0]].x;
var y = points[values[0]].y;

for (var k = 1; k < n; k++)
{
var x2 = points[values[k]].x;
var y2 = points[values[k]].y;

value -= (x-x2) * (x-x2) + (y-y2)*(y-y2);

x = x2;
y = y2;
}

return value;
}

this.getValues = function() { return values; }

this.clone = function(newvalues) {
return new Genotype(points, maxlength, newvalues);
}
}

function Mutator() {
this.mutate = function(genotype) {
if (Math.random() >= 0.5)
return genotype;

var values = genotype.getValues().slice(0);
var l = values.length;

var pos1 = Math.floor(Math.random() * l);
var pos2 = (pos1 + 1) % l;

/* if (Math.random() >= 0.8)
pos2 = Math.floor(Math.random() * l);*/

var value = values[pos1];
values[pos1] = values[pos2];
values[pos2] = value;

return genotype.clone(values);
}
}


</script>

<script language="javascript">
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
Expand All @@ -124,8 +20,8 @@ <h1>Travelling Salesman Problem Sample</h1>
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
for (var k = 0; k < 4; k++)
for (var j = 0; j < 3; j++) {
for (var k = 0; k < 5; k++)
for (var j = 0; j < 4; j++) {
context.arc(50 + 100 * k, 50 + 100 * j, 10, 0, Math.PI * 2, true);
}
context.closePath();
Expand All @@ -150,27 +46,21 @@ <h1>Travelling Salesman Problem Sample</h1>
context.stroke();
}

var points = getPoints(4, 3);
var maxlength = 3 * 4 * (3*3 + 4*4);

var genotype = new Genotype(points, maxlength);
var points = tsp.createPointRectangle(5, 4);
var maxlength = 5 * 4 * (5*5 + 4*4);

drawPoints();
drawValues(points, genotype.getValues());

var engine = new simplega.Engine();

var population = [];

for (var k = 1; k < 5000; k++)
population.push(new Genotype(points, maxlength));
var population = tsp.createPopulation(10000, points, maxlength);

engine.setMutators([new Mutator()]);
engine.setMutators([new tsp.Mutator()]);

var bestvalue = 0;
var bestpath;

setTimeout(doStep, 100);
setTimeout(doStep, 10);

function doStep() {
engine.setPopulation(population);
Expand All @@ -187,15 +77,11 @@ <h1>Travelling Salesman Problem Sample</h1>
}
}

setTimeout(doStep, 100);
setTimeout(doStep, 10);
}


function relaunch() {
var newpopulation = [];

for (var k = 1; k < 5000; k++)
newpopulation.push(new Genotype(points, maxlength));
var newpopulation = tsp.createPopulation(5000, points, maxlength);

bestvalue = 0;
population = newpopulation;
Expand Down
98 changes: 98 additions & 0 deletions samples/tspserver/index.html
@@ -0,0 +1,98 @@
<html>
<head>
<title>Travelling Salesman Problem Sample</title>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<h1>Travelling Salesman Problem Sample</h1>

<div>
<input type="button" value="Restart" onclick="relaunch()">
<input type="button" value="Stop" onclick="stop()">
</div>

<div>
<canvas id="canvas" width="600" height="500">
</canvas>
</div>

<script>

function newResult(msg)
{
if (msg.value > bestpath)
return;

bestpath = msg.value;
drawPoints();
drawValues(points, msg.values);
}

function relaunch()
{
bestpath = maxlength;
socket.emit('newproblem', { width: 5, height: 4} );
}

function stop()
{
socket.emit('stop');
}

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

function drawPoints()
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
for (var k = 0; k < 5; k++)
for (var j = 0; j < 4; j++) {
context.arc(50 + 100 * k, 50 + 100 * j, 10, 0, Math.PI * 2, true);
}
context.closePath();
context.fill();
}

function drawValues(points, values)
{
context.beginPath();

var l = values.length;
var point = points[values[0]];

context.moveTo(50 + 100 * point.x, 50 + 100 * point.y);

for (var k = 1; k < l; k++) {
point = points[values[k]];
context.lineTo(50 + 100 * point.x, 50 + 100 * point.y);
}

context.closePath();
context.stroke();
}

function createPointRectangle(m, n)
{
var points = [];

for (var k = 0; k < m; k++)
for (var j = 0; j < n; j++)
points.push({ x: k, y: j });

return points;
}

var points = createPointRectangle(5, 4);
var maxlength = 5 * 4 * (5*5 + 4*4);
var bestpath = maxlength;

drawPoints();

var socket = io.connect('http://localhost:8080');
socket.on('newresult', newResult);
socket.on('connect', function () {
socket.emit('newproblem', { width: 5, height: 4} );
});

</script>
50 changes: 50 additions & 0 deletions samples/tspserver/server.js
@@ -0,0 +1,50 @@
var app = require('express')()
, server = require('http').createServer(app)
, io = require('socket.io').listen(server)
, simplega = require('../../')
, tsp = require('../tsp/tsp.js');

server.listen(8080);

app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});

var population;
var engine = new simplega.Engine();
var mutator = new tsp.Mutator();
engine.setMutators([mutator]);

var stopped = false;

io.sockets.on('connection', function (socket) {
socket.on('newproblem', function (data) {
var points = tsp.createPointRectangle(data.width, data.height);
var maxlength = data.width * data.height * (data.width*data.width + data.height*data.height);
population = tsp.createPopulation(5000, points, maxlength);
engine.setPopulation();
stopped = false;

function doStep() {
engine.setPopulation(population);
population = engine.nextPopulation();
var bestvalue = simplega.getBestValue(population);
var bestpath = maxlength - bestvalue;
var l = population.length;
console.log(l + ': ' + bestpath);

for (var k = 0; k < l; k++)
if (population[k].evaluate() == bestvalue)
socket.emit('newresult', { value: bestpath, values: population[k].getValues() });

if (!stopped)
process.nextTick(doStep);
}

process.nextTick(doStep);
});

socket.on('stop', function() {
stopped = true;
});
});

0 comments on commit 8a16b6a

Please sign in to comment.