抱歉英语不好:(
假设我可以以任何方式初步组织食谱和配料数据 我如何通过用户提供的成分有效地进行食谱搜索,最好按照最大匹配进行排序 - 所以,使用最大提供的ingridients并且不包含任何其他ingrs的第一个进行配方,在他们使用较少提供的设置和静止的配方之后没有任何其他的人,他们的食谱有最低额外要求等等?
我所能想到的只是代表像bitmasks这样的食谱,并将所需的位掩码与所有食谱进行比较,但这显然是一种不好的方法。
与Levenstein距离相关的事情我不知道如何在这里使用。
我认为这应该是相当普遍的任务......
答案 0 :(得分:3)
听起来你在谈论集合 - “可用成分”是一套,你想要找到所有食谱,其成分构成其中的一个子集,按大小排序。集合有效地实现为平衡树或哈希表。
当你想要处理不同数量的成分时,它会变得更复杂。
编辑:如果您的配方数据存储在SQL数据库中,实际上应该可以作为SQL查询(将在内部使用hastables和树)有效地完成整个事情。但这将是一个非常复杂的查询;更好地问一个比我更擅长SQL的人(当然你的实际表结构是必要的)。
答案 1 :(得分:2)
实际上,我会使用像Lucene这样的工具,因为它已经知道如何做更多或更少的事情。您的成分将是Lucene索引中的关键字,而配方将是文档。然后你可以搜索Lucene索引,它会给你所有匹配的食谱,甚至可以告诉你信心水平。
Lucene是开源的,具有许多语言的实现,包括.NET,Java,PHP和许多其他语言。有关详细信息,请参阅此link。所有相关项目都在该页面上有一个链接。
答案 2 :(得分:2)
仅用于索引 - 我正在进行一些基准测试,并且我已经测试过第一种方法 - 使用子查询和intarray类型进行PostgreSQL实现。
所以,我有传统的带有表格的规范化数据库
食谱(id,name,descr),pk(id)
ingridients (id,name,descr),pk(id)
r2i (recipe_id,ingridient_id),唯一(recipe_id,ingridient_id)(似乎我不需要那个索引,它等于整个表)
name和descr列中填充了一些垃圾只是为了让表更大;-) 总的来说,我用200种配料填充了表,5000种配方,每种配方有3到10种成分,r2i总共约35k行。
假设我想搜索我的成分集129,99,56,180的食谱 查询将如下所示:
SELECT recipe_id, recipe_ingrs, icount('{129,99,56,180}'::int[] - recipe_ingrs) as shortage, icount(recipe_ingrs - '{129,99,56,180}'::int[]) as excess
FROM (
SELECT id as recipe_id, array(select ingridient_id from r2i where r2i.recipe_id = recipes.id)::int[] as recipe_ingrs
FROM recipes WHERE recipes.id IN (select distinct recipe_id from r2i where ingridient_id IN (129,99,56,180))
) as t
ORDER BY excess ASC, shortage ASC;
查询成本约为7k(取决于您查询的设置),但在我的Windows测试笔记本电脑(c2duo,2gb ram)上运行速度非常快 - 即时供人眼使用:)
关于intarray类型有doc available。
测试尚未完成,我还有两个测试解决方案,+获得一些关于速度的数据。