抱歉,我无法提出以下算法的算法名称或问题。我将陈述问题,然后我尝试过,也许有人可以指出我正确的方向。
想象一下你有一袋物品(无序,重复允许)。在实践中,袋子可能包含2-20个物品,以防松弛。
目标是找到最小长度链(如果我们有不同的链概念,有序链接列表),其中包含任何顺序的包中的所有项目。
一个链包含一个开始标记(不包含在包中),后跟任意数量的项目,后跟一个结束标记(也不在包中)。
通过将n元组拼接在一起形成链(顺序很重要),作为进一步的放松,让我们说n值对于所有元组都是相同的。在实践中,我正在使用n = 3.链条可以“混合”而不是连接,如果它们具有重叠元素。例如,考虑(a,b,c)和(c,d,e)。可以作为(a,b,c,d,e)连接。同样地,(a,b,c)和(b,c,d)可以连接为(a,b,c,d)。一些元组可能在第一个位置有一个开始标记,而一些标记在最后一个位置有一个结束标记,这当然可以解决问题。
因此,在我看来,问题的确切解决方案一般不易处理。为了获得问题的“好”解决方案,需要某种优化算法。我可以忍受的“好”解决方案。
我开始使用的是一种贪婪的方法,在第一遍中,你会发现包含袋中元素数量最多的元组,任意断开关系。创建一个数据结构,它保存我们迄今为止构建的链,并将选定的元组粘贴到此数据结构中。将问题拆分为2个子问题,即开始令牌侧和结束令牌侧。在子问题1的数据结构的第一个标记是起始标记并且子问题2的最后一个标记是结束标记之前,增长链以使我们尽快找到停止条件(开始或结束标记取决于在子问题上,同时也试图尽快排出袋子的内容。这可能不太好,因为每个子问题必须相互沟通,以确定需要包含多少物品。
有人在任何地方看到过这个问题吗有关如何改进(或正常工作)此算法的任何想法?这是我正在解决的一个真正的问题,它是一个更大系统的智能部分,不是玩具问题或家庭作业问题。
修改
对不起,我今天一直都不在电脑前。我将尝试发布一个示例解决方案,该解决方案不是太微不足道,但也不会太复杂,无法看到。
假设:
Bag = {A, B, C, D}
(为了示例,我将其设为一组,但每个项目可以出现多次)/ = Start Token
\ = End Token
3元组(三元组):为了简化命名,我将它们标记为a-g。小写字母在问题中没有实际功能。
(/,A, E) a
(/,C, D) b
(/,G, H) c
(D,B, A) d
(C,G, H) e
(B,A, \) f
(G,H, \) g
解决方案:如果我们将b,d和f链接在一起,我们得到(/,C,D,B,A,\)
这是包含包中所有元素的最短链,如果计算开始和结束标记,则该长度为6。通常,最短路径的长度为| BAG | + 2,如果它确实存在。我希望我的问题陈述现在更有意义。
答案 0 :(得分:2)
由于您最多只有20个项目,我认为您可以在合理的时间内(例如,不到一分钟)计算出精确的解决方案。
一种方法是使用动态编程,其中状态由下式给出:
A) a 20 bit number m (which will represent which items have been visited so far)
B) a number b in the range 1..20
C) a number c in the range 1..20
此状态对应于看起来像Start,?,?,?,...,?,b,c的链。 即b和c是最近的2个元素。
数字m是一个位域,表示链中访问了哪些其他元素。换句话说,当且仅当链包括袋中的第i个元素时,m的位i为1。
找到最短链的算法将是:
如果您设法添加包含结束状态的元组,那么您已找到包含所有元素的最短链。
对于包中的N个项目,大约有2 ^ N.N.N个状态应该是可管理的。