只是为了好玩,我正在创建旅行商问题的基本 JavaScript 实现。
它基本上会创建一个具有随机坐标的城市数组,将它们绘制在画布上,然后显示它们之间的路径。然后我有一个按钮可以启动“findBetterRoute”功能,它只是交换两个城市,如果路径更好,它将返回新路线,如果更糟,它将返回原始路线。但是,我发现最后一部分不起作用 - 它有时会绘制一条比原始路线更长的路线,而我终生无法理解我做错了什么。
这是我的代码:
<html>
<head>
<title>The Traveling Salesman Problem</title>
</head>
<body onload="drawInitial()">
<canvas id="TSP" width="1000" height="1000" style="border:1px solid #000000;"></canvas>
<script>
var canvas = document.getElementById("TSP");
var ctx = canvas.getContext("2d");
var numberofCities = 5;
let city = [numberofCities];
for (i = 0; i < numberofCities; i++) {
city[i] = [Math.random() * 1000 + 1, Math.random() * 1000 + 1];
}
function drawInitial() {
drawPath(city);
}
function drawPath(cityarray) {
ctx.moveTo(cityarray[0][0], cityarray[0][1]);
for (i = 0; i < cityarray.length; i++) {
if (i != 0) {
ctx.lineTo(cityarray[i][0], cityarray[i][1]);
ctx.stroke();
}
ctx.beginPath();
ctx.arc(cityarray[i][0], cityarray[i][1], 2, 0, Math.PI * 2, true);
ctx.fill();
}
ctx.lineTo(city[0][0], city[0][1]);
ctx.stroke();
ctx.font = "30px Arial";
ctx.fillText("Path Length: " + parseInt(calculatePathLength(city)), 10, 50);
}
function calculatePathLength(cityarray) {
let pathLength = 0;
for (i = 0; i < (cityarray.length - 1); i++) {
pathLength = pathLength + Math.sqrt((Math.pow((cityarray[i][0] - cityarray[i + 1][0]), 2)) + (Math.pow((cityarray[i][1] - cityarray[i + 1][1]), 2)))
}
pathLength = pathLength + Math.sqrt((Math.pow((cityarray[numberofCities - 1][0] - cityarray[0][0]), 2)) + (Math.pow((cityarray[numberofCities - 1][1] - cityarray[0][1]), 2)))
return pathLength;
}
function swap2RandomCities(cityarray) {
var city1 = 1;
var city2 = 2;
do {
city1 = parseInt(Math.random() * numberofCities);
city2 = parseInt(Math.random() * numberofCities);
} while (city1 == city2);
var swapArray = [];
swapArray[0] = [cityarray[city1][0], cityarray[city1][1]];
swapArray[1] = [cityarray[city2][0], cityarray[city2][1]];
cityarray[city1] = swapArray[1];
cityarray[city2] = swapArray[0];
return cityarray;
}
function findBetterRoute(cityArray) {
var currentlength = calculatePathLength(cityArray);
var newRoute = swap2RandomCities(cityArray);
if (calculatePathLength(newRoute) < currentlength) {
return newRoute;
} else {
return cityArray;
}
}
function ButtonClick() {
city = findBetterRoute(city);
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawPath(city);
}
</script>
<button onclick="ButtonClick()">Find Better Route</button>
</body>
</html>