【问题标题】:Any efficient easy way to find the maximum list among N lists with the same length using Mathematica?使用 Mathematica 在具有相同长度的 N 个列表中找到最大列表的任何有效简单方法?
【发布时间】:2012-01-17 04:17:35
【问题描述】:

这个问题是上一个线程的延续,比较两个具有相同长度的列表:

Is there any efficient easy way to compare two lists with the same length with Mathematica?

给定两个列表A={a1,a2,a3,...an}B={b1,b2,b3,...bn},我会说A>=B 当且仅当所有ai>=bi。现在我们有k 列表H={{a11,a12,a13,...a1n}, {a21,a22,a23,...a2n},...,{ak1,ak2,ak3,...akn}},如果存在,我们想找到最大的一个。

这是我的代码:

Do[If[NonNegative[Min[H[[i]] - h]], h = H[[i]], ## &[]], {i, h = H[[1]]; 1, Length[H]}];h

有什么更好的技巧吗?

编辑:

我想将其定义为如下函数:

maxList[H_]:=Do[If[NonNegative[Min[H[[i]] - h]], h = H[[i]], ## &[]], {i, h = H[[1]]; 1, Length[H]}];h

但问题是上面的代码跨越了两行,有什么解决办法吗?这是一些有效的代码,但不是那么漂亮

maxList[H_] := Module[{h = H[[1]]}, Do[If[NonNegative[Min[H[[i]] - h]], h = H[[i]], ## &[]], {i, Length[H]}]; h]

maxList[H_]:=Last[Table[If[NonNegative[Min[H[[i]] - h]], h = H[[i]], ## &[]], {i, h = H[[1]]; 1, Length[H]}]]

【问题讨论】:

    标签: arrays list wolfram-mathematica mathematica-8


    【解决方案1】:

    在我看来这应该可行:

    maxList = # \[Intersection] {Max /@ Transpose@#} &;
    
    maxList[ {{4, 5, 6}, {1, 4, 3}, {4, 3, 5}, {5, 6, 7}} ]
    
    {{5, 6, 7}}
    

    我没有考虑使用Intersection 的成本,Artes 表明MemberQ 是一个更好的选择。 (请像我一样投票给他的答案)。我会自己编写函数而不使用Module

    maxList[a_] := If[MemberQ[a, #], #, {}] &[Max /@ Transpose@a]
    

    一个几乎等效但不是 相当 的快速方法是这样的:

    maxList = Cases[#, Max /@ Transpose@# , 1, 1] &;
    

    结果的格式为{{a, b, c}}{},而不是{a, b, c}{}

    【讨论】:

    • 使用Max /@而不是Last /@ Sort /@会更高效。
    • @celtschk 确实;与 Osiris 之前的问题一样,我正在考虑泛化,尽管我没有说明这一点,我也没有展示如何使用自定义比较器。使用OrderingPart 作为kguler 的广义形式会更有效。我将重新考虑这个答案的价值。
    【解决方案2】:

    对 Mr.Wizard 的方法进行修改后,工作速度提高了几倍。

    maxListFast[list_List] := Module[{l}, 
                                     l = Max /@ Transpose@list; 
                                     If[MemberQ[list, l], l, {}]]
    

    我们用

    测试这两种方法
    test  = RandomInteger[100, {500000, 10}];
    test1 = Insert[test, Table[100, {10}], RandomInteger[{1, 500000}]]; 
    

    我们得到

    In[5]:= maxList[test] // Timing
            maxListFast[test] // Timing
    
            Out[5]= {2.761, {}}
            Out[6]= {0.265, {}}
    

    In[7]:= maxList[test1] // Timing
            maxListFast[test1] // Timing
    
    Out[7]= {1.217, {{100, 100, 100, 100, 100, 100, 100, 100, 100, 100}}}
    Out[8]= {0.14, {100, 100, 100, 100, 100, 100, 100, 100, 100, 100}}
    

    编辑

    一般来说,选择一种方法,我们首先应该知道我们要处理什么样的数据。 (列表的长度、数量、数字类型)。虽然我们有大量的短名单 整数 maxListFast 的工作效率甚至比 maxList 好 10 倍(在 500000 个长度为 10 的列表的情况下)。 然而,对于实数列表,它只快 3-4 倍,而且我们拥有的列表越多越长,它的速度就越慢,例如:

             A = RandomReal[1000, {3000, 3000}];
             First@AbsoluteTiming[maxListFast@A;]/ First@AbsoluteTiming[maxList@A;]
    
    Out[19]= 2.040516    
    

    但是,如果我们插入“最大元素”:

    In[21]:= IA = Insert[A, Table[1000, {3000}], RandomInteger[{1, 3000}]];
    In[22]:= First@AbsoluteTiming[maxListFast@IA;]/ First@AbsoluteTiming[maxList@IA;]
    
    Out[22]= 0.9781931
    

    时间接近。

    【讨论】:

    • 我没有查看Intersection 的费用。很好的收获。
    • IntersectionMemberQ 的成本取决于数据的维度。如果您比较maxListmaxListFast 上的数据Transpose[test],时序排名可以颠倒。
    • @Mr.Wizard 感谢您的支持,我一直在添加一个没有模块的简洁方法,但您已经先完成了。虽然这两种方法在性能方面似乎非常相似。
    • Artes,恭喜您获得接受的答案。请考虑将您的代码更新为您想出的无模块版本,或者如果您愿意,可以使用我的。
    • @Mr.Wizard 谢谢。事实上,Module-free 版本更优雅一些。然而,全面更新以描述问题的具体案例方面需要相当长的时间,我现在很怀念。
    【解决方案3】:

    一些数据:顺便说一句,实际上没有必要标记各个子列表。我这样做是为了方便参考。

    a = {4, 5, 6}; b = {1, 4, 3}; c = {4, 3, 5}; d = {5, 6, 7};
    
    lists = {a, b, c, d};
    

    ma​​xList 确定子列表是否为最大列表,即它的每个元素是否大于所有其他子列表中的相应元素。我们最初假设子列表是最大列表。如果违反该假设(注意使用Negative 而不是NonNegative)则返回False。顺便说一句,列表将与自身进行比较;这比从lists 中删除要容易;并且不影响结果。

    maxList[list_] :=
       Module[{result = True, n = 1},
       While[n < Length[lists] + 1, 
       If[Negative[Min[list - lists[[n]]]], result = False; Break[]];  n++]; result]
    

    现在让我们检查上述子列表之一是否为 maxList:

    greatestList = {};
    n = 1; While[n < Length[lists] + 1, 
    If[maxList[lists[[n]]], greatestList = lists[[n]]; Break[]]; n++];
    Print["The greatest list (if one exists): ", greatestList]
    
    (* output *)
    The greatest list (if one exists): {5,6,7}
    

    子列表 d 是一个 maxList。

    如果没有 maxList,则结果将是空列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多