从每个列表中最佳选择一个元素
|
我遇到了您可能喜欢Mathematica / StackOverflow的人们遇到的一个老问题,对于后代来说,在StackOverflow上看起来很有价值。
假设您有一个列表列表,并且想从每个列表中选择一个元素,然后将它们放在新列表中,以使与其下一个相邻元素相同的元素数量最大化。
换句话说,对于结果列表l,最小化Length @ Split [l]。
换句话说,我们希望列表中相同连续元素的中断最少。
例如:
pick[{ {1,2,3}, {2,3}, {1}, {1,3,4}, {4,1} }]
--> { 2, 2, 1, 1, 1 }
(或者{3,3,1,1,1}同样好。)
这是一个荒谬的蛮力解决方案:
pick[x_] := argMax[-Length@Split[#]&, Tuples[x]]
其中argMax如下所述:
posmax:类似于argmax,但给出f [x]最大的元素x的位置
你能想出更好的东西吗?
传奇人物卡尔·沃尔(Carl Woll)为我做到了这一点,我将在一周内揭示他的解决方案。
没有找到相关结果
已邀请:
8 个回复
荆怖赡
给出游程长度编码的输出,包括并行答案。如果需要严格指定的输出,请使用:
这是使用折页的一种变体。在某些设置的形状上速度更快,而在其他设置的形状上速度稍慢。
抹持奠糙驰
其中rl涉及的子集数量。 对于以这种方式生成的每个测试集,我都有所有算法来做。我用随机顺序运行的算法做了10次(使用相同的测试集),以使顺序效果和笔记本电脑上的随机后台进程的效果趋于平稳。这将导致给定数据集的平均计时。对于每个rl长度,将上述行使用20次,从中计算出平均值(均值)和标准差。 结果如下(水平子集数量,垂直绝对平均值): 向导先生似乎是(不清楚)赢家。恭喜! 更新资料 根据Timo的要求,时序取决于可从中选择的不同子集元素的数量以及每个子集中元素的最大数量。根据以下代码行为固定数量的子集(50)生成数据集:
我还将为每个值尝试的数据集数量从20增加到40。 这里有5个子集:
鞘垒飘
一些画廊:
鉴于Sjoerd's Dreeves的蛮力方法由于无法一次生成所有元组而无法在大样本上使用,因此进行编辑,这是另一种蛮力方法:
这种强力最佳选择可能会产生不同的分裂,但是根据原始问题,长度才是最重要的。
在此示例中选择失败。
我发布此消息是为了防止有人想搜索诸如pickPath或LongestRuns之类的代码确实生成中断次数最少的序列的反例。
疮痪徘弦漏
换为
,并插入零以表示缺失的数字。它显示了其中出现1、2、3和4的子列表。 myPick:挑选构成最佳路径的数字
递归建立最长运行时间的列表。它不会寻找所有最佳解决方案,而是寻找最小长度的第一个解决方案。
感谢Wizard先生建议使用替代规则作为ѭ18的有效替代方法。 Epilog:可视化解决方案路径
下图表示来自
的数据。 每个标绘点都对应一个数字及其所在的子列表。
咳累录酬
它基本上在连续的列表上重复使用交集,直到它变空为止,然后一次又一次地使用它。在一个巨大的酷刑测试案例中
我在2GHz Core 2 Duo上始终获得0.023英镑的23英镑。 这是我的第一次尝试,将留给您仔细阅读。 对于元素of24ѭ的给定列表,我们计算不同的元素和列表的数量,以规范的顺序列出不同的元素,并构造矩阵
,详细说明列表
中元素
的存在:
现在的问题等效于仅踩1并尽可能少地更改行,从而从左到右遍历此矩阵。 要实现此目的,我要对行进行“ѭ29”操作,以开始时最连续的1 \开头,跟踪我选择的元素,从“ѭ31”中选择那么多的行“ѭ30”,然后重复:
它的S33ѭ约为Sjoerd的方法的三倍。
厘恼轨
测试
德瑞夫斯的蛮力法
我第一次使用略长的测试列表。蛮力方法使我的计算机陷入了虚拟停顿,声称拥有它的所有内存。很糟糕。我必须在10分钟后重新启动。重新启动又花了我25分钟的时间,这是因为PC变得非常无响应。
可扇胆
你的例子:
Out [88] = {1,{2,2,1,1,1}} 对于较大的问题,Minimize可能会遇到麻烦,因为它使用精确的方法来解决宽松的LP。在这种情况下,您可能需要切换到NMinimize,并将domain参数更改为Element [fvars,Integers]形式的约束。 丹尼尔·里奇布劳
布埃郝卞簿
仍引用Carl: 基本上,您从头开始,然后找到可以为您提供帮助的元素 最长的公共元素字符串。一旦字符串不能再被 扩展,开始一个新的字符串。在我看来,这种算法应该 给您一个正确的答案(有很多正确的答案)。