我已经编写了这个回溯算法,从10个项目的输入数组中制作出70个项目的混乱数组。它需要遵循的规则是:
这几乎可以工作,但只有当我使输入数组大于我的输出数组时才会破坏规则3.如果我使输入数组的长度为70,那么算法有时会工作但有时会溢出。
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html" />
<title>Backtracking Pseudo Randomiser</title>
</head>
<body>
<button onclick=go();>Go</button>
<script>
function go() {
function pseudoRan(input,output) {
if (output.length==70) {
output=listToMatrix(output,5);
printIt(output);
return;
}
else {
var tmp=input.shift();
var mod=output.length % 5;
if (output.slice(-mod-1).indexOf(tmp)==-1 && output[output.length-5]!=tmp && output[output.length-10]!=tmp) {
output.push(tmp);
pseudoRan(input,output);
}
else {
input.push(tmp);
pseudoRan(input,output);
}
}
}
var input=["A","B","C","D","E","F","G","H","I","K"];
var output=[];
input=pool(input,70);
input=yatesShuffle(input);
pseudoRan(input, output);
//analyse it
var freqs=output.byCount();
var strFreqs="";
for(a=0;a<freqs.length;a++){
strFreqs+="Item: " + freqs[a].item + " ..." + freqs[a].frequency + "<br />";
document.getElementById("2").innerHTML=strFreqs;
}
}
function pool(array,total) {
var factor=total/array.length;
var newArray=[];
for (a=0;a<factor;a++) {
for (b=0;b<array.length;b++) {
newArray.push(array[b]);
}
}
//console.log(newArray);
return newArray;
}
function yatesShuffle (array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * i); // no +1 here!
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function listToMatrix(list, elementsPerSubArray) {
var matrix = [], i, k;
for (i = 0, k = -1; i < list.length; i++) {
if (i % elementsPerSubArray === 0) {
k++;
matrix[k] = [];
}
matrix[k].push(list[i]);
}
return matrix;
}
function printIt(array) {
for (i=0;i<array.length;i++) {
var str=" ";
for (j=0;j<array[i].length;j++) {
str+=array[i][j]+" ";
}
document.getElementById("1").insertAdjacentHTML('beforeend',str + "</br>");
//console.log(array[i]);
}
}
Array.prototype.byCount= function(){
var itm, a= [], L= this.length, o= {};
for(var i= 0; i<L; i++){
itm= this[i];
if(!itm) continue;
if(o[itm]== undefined) o[itm]= 1;
else ++o[itm];
}
for(var p in o) a[a.length]= {item: p, frequency: o[p]};
return a.sort(function(a, b){
return o[b.item]-o[a.item];
});
}
</script>
<div id="1" style="font-family:'Courier New';"></div>
<br />
<div id="2"></div>
</body>
</html>
答案 0 :(得分:1)
没有太多的输入是一个问题。如果你运行代码足够多次,我认为你会发现它有时会起作用,但有时候,根据shuffle的结果,只是不可能将任何剩余的输入放到输出数组上。
就像玩Solitaire一样:可能在开始时就是的解决方案,但根据您所做的决定(从输入数组中挑选项目),您可能仍会失败。
如果你完全通过输入数组循环而没有任何成功,你应该至少跟踪。
如果您完全通过输入列表循环但没有成功,那么您永远不会。然后你有几个选择:
一种方法:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html" />
<title>Backtracking Pseudo Randomiser</title>
</head>
<body>
<button onclick=go();>Go</button>
<script>
function go() {
var tracker = 0
function pseudoRan(input,output) {
if (output.length==70) {
output=listToMatrix(output,5);
printIt(output);
return true;
}
else {
var tmp=input.shift();
var mod=output.length % 5;
console.log('input.length::tracker ==>', input.length + '::' + tracker)
if (output.slice(-mod-1).indexOf(tmp)==-1 && output[output.length-5]!=tmp && output[output.length-10]!=tmp) {
tracker = 0
output.push(tmp);
return pseudoRan(input,output);
}
else {
tracker++
if (tracker > input.length) {
console.log('Failed this time.')
output=listToMatrix(output,5);
console.log('output-----------------------');
printIt(output);
console.log('input------------------------');
printIt(input);
return false // FAILED to finish
}
input.push(tmp);
return pseudoRan(input,output);
}
}
}
var input=["A","B","C","D","E","F","G","H","I","K"];
input=pool(input,300);
// run until we get an answer
do {
var output=[];
tracker = 0;
// operate on copy of the data
runInput=yatesShuffle(JSON.parse(JSON.stringify(input)));
} while (!pseudoRan(runInput, output))
// analyse it
var freqs=output.byCount();
var strFreqs="";
for(a=0;a<freqs.length;a++){
strFreqs+="Item: " + freqs[a].item + " ..." + freqs[a].frequency + "<br />";
document.getElementById("2").innerHTML=strFreqs;
}
}
function pool(array,total) {
var factor=total/array.length;
var newArray=[];
for (a=0;a<factor;a++) {
for (b=0;b<array.length;b++) {
newArray.push(array[b]);
}
}
//console.log(newArray);
return newArray;
}
function yatesShuffle (array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * i); // no +1 here!
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function listToMatrix(list, elementsPerSubArray) {
var matrix = [], i, k;
for (i = 0, k = -1; i < list.length; i++) {
if (i % elementsPerSubArray === 0) {
k++;
matrix[k] = [];
}
matrix[k].push(list[i]);
}
return matrix;
}
function printIt(array) {
for (i=0;i<array.length;i++) {
var str=" ";
for (j=0;j<array[i].length;j++) {
str+=array[i][j]+" ";
}
document.getElementById("1").insertAdjacentHTML('beforeend',str + "</br>");
console.log(array[i]);
}
}
Array.prototype.byCount= function(){
var itm, a= [], L= this.length, o= {};
for(var i= 0; i<L; i++){
itm= this[i];
if(!itm) continue;
if(o[itm]== undefined) o[itm]= 1;
else ++o[itm];
}
for(var p in o) a[a.length]= {item: p, frequency: o[p]};
return a.sort(function(a, b){
return o[b.item]-o[a.item];
});
}
</script>
<div id="1" style="font-family:'Courier New';"></div>
<br />
<div id="2"></div>
</body>
</html>