使用Mathematica在N个列表中查找具有相同长度的最大列表的任何有效简便方法?

时间:2012-01-17 04:17:36

标签: arrays list wolfram-mathematica mathematica-8

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

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]}]]

3 个答案:

答案 0 :(得分:5)

在我看来,这应该有效:

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}{}

答案 1 :(得分:3)

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倍(如果长度为10的500000个列表)。 然而,对于实数列表,它仅快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
时间关闭。

答案 2 :(得分:2)

一些数据:顺便说一下,实际上并不需要标记各个子列表。我这样做是为了方便参考。

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

lists = {a, b, c, d};

maxList 确定子列表是否是最大列表,即其每个元素是否大于所有其他子列表中的相应元素。我们最初假设子列表是最大列表。如果违反了该假设(注意使用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,结果将是空列表。