对于您给出的数字,只需蛮力就可以了。
这是一个JavaScript程序,它针对数据库中的10种成分,数据库中的10种配方对其进行强行强制处理,每个配方需要2种成分,而我有5种可用成分:
var i, j;
var numIngredients = 10;
var numRecipes = 10;
var numIngredientsPerRecipe = 2;
var numIngredientsInQuery = 5;
function containsAll(needles, haystack){
var i, len;
for(i = 0 , len = needles.length; i < len; i++){
if(haystack.indexOf(needles[i]) == -1) {
return false;
}
}
return true;
}
// Set up a fake DB of recipes
var ingredients = [];
for (i = 0; i < numIngredients; i++) {
ingredients.push(i);
}
console.log('Here are the ingredients:', ingredients);
var recipes = [];
for (i = 0; i < numRecipes; i++) {
var neededIngredients = [];
for (j = 0; j < numIngredientsPerRecipe; j++) {
neededIngredients.push(Math.floor(Math.random() * numRecipes));
}
recipes.push({ recipeId: i, needed: neededIngredients});
}
console.log('Here are the recipes:', recipes);
// Set up a fake query
var ingredientsAvailable = [];
for (i = 0; i < numIngredientsInQuery; i++) {
ingredientsAvailable.push(Math.floor(Math.random() * numRecipes));
}
console.log("Here's a query:", ingredientsAvailable);
//Time how long brute force takes
var start = Date.now();
var result = [];
for (i = 0; i < numRecipes; i++) {
var candidateRecipe = recipes[i];
if (containsAll(candidateRecipe.needed, ingredientsAvailable)) {
result.push(candidateRecipe);
}
}
var end = Date.now();
console.log('Found ' + result.length + ' recipes in ' + (end - start) + ' milliseconds.');
console.log(result);
它在0毫秒内运行。我选择了这些较小的数字,以便您可以自己运行几次,并说服自己做到了您想要的并且相对没有错误。
现在更改它,以便我们在数据库中有1'000'000个成分,在数据库中有1'000'000个配方,每个配方50个成分以及100种可用的成分。即所有等于或大于您给出的最大用例的值。
它在nodejs下运行的时间为125毫秒,这是最愚蠢的实现,完全无需优化。