【发布时间】:2015-03-09 14:22:33
【问题描述】:
我正在尝试从嵌套数组中提取所有可能的非重叠组以产生最少数量的组
{
0: 4, 5, 6
1: 4, 5
2: 3, 4 ,9
3: 8, 9
4: 8,10,11
5: 8,10,11
}
从 0 到 5,以下是可能的最佳结果:
- [[4,4,4],[8,8,8]]
- [[5,5],[9,9],[10,10]]
- [[5,5],[9,9],[11,11]]
1 组更好,因为它只有两组。
我知道如何在多个循环中执行此操作,但有什么方法可以一次性完成吗?感觉可能是寻路问题,但不知道如何转换成一个。
解决方案
我设计了一个基于 libik 在下面的答案(使用 JS)的方法,只用了 19 个周期!
function bestPath(){
var array = [[4,5,6],[4,5],[3,4,9],[8,9],[8,10,11],[8,10,11]],
arrayOfIndexes = (function (){
var arr = [];
for (var k=0; k < array.length; k++){
arr.push({
index: array[k].length-1,
last_split: 0
})
}
//dummy index, needed for jumping back
arr.push({index:0, last_split:0});
return arr;
})();
// This function clones the current working path
// up to a specific index (which we then use to
// rebuild upon by taking another route)
var cloneTill = function(array, till){
var new_arr = [];
for (var l=0; l < till; l++)
new_arr.push( array[l] );
return new_arr;
};
var numset = 0, // running counter of num. sets in working path
bestset = 99999;
var path_list = [], // array of all paths
best_path = null, //
temppath = []; // current working path
var row = 0,
min_stretch_len = 2; // minimum length heuristic
while (true){
var color_index = arrayOfIndexes[row];
console.log("path="+temppath);
var jumpBack = false;
if (row === 0){
if (color_index.index < 0) break; //No more paths to explore after jumping back.
numset = 0;
}
if (row === array.length){
if (numset < bestset){
bestset = numset;
best_path = temppath;
}
path_list.push ( temppath );
jumpBack = true;
}
if (color_index.index < 0) jumpBack = true;
if (jumpBack){
// console.log( ">>jumprow:"+row+"-->"+color_index.last_split
// +", index to:"+(arrayOfIndexes[color_index.last_split].index - 1)+'\n');
// jump back to last split
row = color_index.last_split;
temppath = cloneTill(temppath, row);
arrayOfIndexes[row].index--;
continue;
}
//We have an unexplored color
var color = array[row][color_index.index];
// console.log(" trying color='"+color+"'");
//Perform lookahead
var stretch = row;
while ( stretch < array.length && array[stretch].indexOf(color)!== -1){
temppath.push(color);
stretch ++;
}
stretch -= row;
// Unsuccessful
if (stretch < min_stretch_len){
// console.log(" failed (too short)");
while(stretch --> 0) temppath.pop(); // clear changes
arrayOfIndexes[row].index--; // next attempt at this row will try a different index
continue;
}
// Successfully found a new color. Splitting
// console.log(" worked, arrayOfIndexes["+(row+stretch)+"].last_split = "+row);
arrayOfIndexes[row+stretch].last_split = row; // this row is where we split
row += stretch;
numset ++;
}
console.log("sols", path_list);
console.log("best path=", best_path);
}
【问题讨论】:
-
我很确定复杂性不是 O(n),因此你不能在“单程”中做到这一点。我什至认为它是 O(k^n),其中 k 是行数,n 是行数。
-
公平。只是想我会检查
-
我一直在努力实现这一点,我可以指点一下吗?
标签: arrays traversal path-finding