答案 0 :(得分:1)
递归有两个主要的想法,第一个是每个步骤的问题(所以在这种情况下是董事会)你解决问题应该变得更小。第二个重要的想法是每个步骤都是一样的。
因此,在这种情况下,您可以放置一块,然后在板上再次调用该功能,同时移除放置的部件。让我们再深入了解它们。
希望这有帮助!
答案 1 :(得分:1)
这是一个相当幼稚的算法实现,可以帮助您入门。
它正在寻找一个完美的解决方案(董事会完全填满),并在找到一个解决方案后立即退出。这将按照您的示例板的预期工作,但它可能会永远运行其他没有简单完美解决方案的板,或根本没有完美的解决方案。
更好的算法是:
此算法中唯一的改进是使用哈希表来避免两次访问同一个板,当两个不同的移动组合产生相同的配置时。
电路板的每一行都表示为一个字节,每一部分表示为2x2位。
var b = [
// initial board
0b00000000,
0b00000000,
0b00000100,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
],
piece = [
// bitmasks of pieces as [ top_bitmask, bottom_bitmask ]
[ 0b11, 0b01 ], [ 0b11, 0b10 ], [ 0b01, 0b11 ], [ 0b10, 0b11 ]
],
// hash table of visited boards
hash = {},
// statistics
node = 0, hit = 0;
function solve(sol) {
var x, y, p, s;
// compute hexadecimal key representing the current board
var key =
((b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24)) >>> 0).toString(16) + '-' +
((b[4] | (b[5] << 8) | (b[6] << 16) | (b[7] << 24)) >>> 0).toString(16);
node++;
if(hash[key]) {
// abort immediately if this board was already visited
hit++;
return false;
}
if(key == 'ffffffff-ffffffff') {
// return the current solution if the board is entirely filled
return sol;
}
// save board in hash table
hash[key] = true;
// for each position and each type of piece ...
for(y = 0; y < 7; y++) {
for(x = 0; x < 7; x++) {
for(p = 0; p < 4; p++) {
// ... see if we can insert this piece at this position
if(!(b[y] & (piece[p][0] << x)) && !(b[y + 1] & (piece[p][1] << x))) {
// make this move
b[y] ^= piece[p][0] << x;
b[y + 1] ^= piece[p][1] << x;
// add this move to the solution and process recursive call
s = solve(sol.concat(x, y, p));
// unmake this move
b[y] ^= piece[p][0] << x;
b[y + 1] ^= piece[p][1] << x;
// if we have a solution, return it
if(s) {
return s;
}
}
}
}
}
return false;
}
function display(sol) {
var n, x, y, html = '';
for(n = 0; n < 64; n++) {
html += '<div class="cell"></div>';
}
$('#container').html(html);
for(n = 0; n < sol.length; n += 3) {
for(y = 0; y < 2; y++) {
for(x = 0; x < 2; x++) {
if(piece[sol[n + 2]][y] & (1 << x)) {
$('.cell').eq(7 - sol[n] - x + (sol[n + 1] + y) * 8)
.addClass('c' + sol[n + 2]);
}
}
}
}
}
setTimeout(function() {
display(solve([]));
console.log(node + ' nodes visited');
console.log(hit + ' hash table hits');
}, 500);
&#13;
#container { width:160px; height:160px }
.cell { width:19px; height:19px; margin:1px 1px 0 0; background-color:#777; float:left }
.c0 { background-color:#fb4 }
.c1 { background-color:#f8f }
.c2 { background-color:#4bf }
.c3 { background-color:#4d8 }
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">Searching...</div>
&#13;