二、一些思考
最让人想到的就是拓扑排序,不过这种问题在高级语言中通常都可以直接用暴力的方法得到。另外,单纯就这道题的解决方法可以解决很多现实中的问题。比如餐厅原料订购与本餐厅菜谱之间的匹配问题,工厂生产中产品与原料的匹对问题,这些都是在日常后勤中所应用的,不过通常都会带上权重。尤其在原材料和产品都比较多的情况下,利用计算机解决可以提高工作效率。
这些在仓库管理系统中也是常应用到的。仓库的职责通常来说就是采购、出料与产品入库,而当工厂生产产品多时,如何就当前生产计划以及现有原料库存量推算出预采购原料量是节约成本的重要环节。有些原料有保存期限,再加上库房空间上的限制,有时问题会变得较为复杂,难以通过人力在较短的时间内得出最优方案。这时,采用线性规划以及拓扑排序等方法建立有效的计算机处理模型变得极为重要。
三、非拓扑排序解决
var findAllRecipes = function(recipes, ingredients, supplies) {
let ok = [];
let wait = [];
for(let i = 0; i < recipes.length; i++) {
let have = 0;
for(let j = 0; j < ingredients[i].length; j++) {
let o_i = -1;
if(supplies.indexOf(ingredients[i][j]) >= 0) {
have++;
} else if((o_i = recipes.indexOf(ingredients[i][j])) >= 0) {
if(wait[i] == undefined) {
wait[i] = [];
wait[i].push(o_i);
} else {
wait[i].push(o_i);
}
} else {
delete wait[i];
break;
}
}
if(have == ingredients[i].length) {
ok.push(i);
}
}
let wait_r = Object.keys(wait);
let init_l = wait_r.length;
let before_circle = 0;
let last_circle = 0;
let cur_start = 0;
for(let u = 0; u < wait_r.length; u++) {
let o = 0;
let all = wait[wait_r[u]].length;
for(let f = 0; f < wait[wait_r[u]].length; f++) {
if(ok.indexOf(wait[wait_r[u]][f]) >= 0) {
o++;
wait[wait_r[u]].splice(f,1);
f--;
} else if(wait_r.indexOf(wait[wait_r[u]][f] + '', u) >= 0) {
wait_r.push(wait_r[u]);
last_circle++;
break;
} else {
break;
}
}
if(o == all) {
ok.push(parseInt(wait_r[u]));
}
//出现环 产生死锁
if(u - cur_start >= init_l && before_circle == last_circle) {
break;
}
if(u - cur_start >= init_l) {
init_l = last_circle;
cur_start = u;
before_circle = last_circle;
last_circle = 0;
}
}
let result = [];
for(let i =0; i < ok.length; i++) {
result.push(recipes[ok[i]]);
}
return result;
};