2

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

是否有任何有效的简单方法可以将两个具有相同长度的列表与 Mathematica 进行比较?

给定两个列表A={a1,a2,a3,...an}and B={b1,b2,b3,...bn},我会说A>=B当且仅当 all 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]}]]

4

3 回答 3

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}}or{}而不是{a, b, c}or {}

于 2012-01-17T08:29:31.770 回答
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. 然而,对于实数列表,它只快 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

计时关闭。

于 2012-01-17T15:05:52.657 回答
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,则结果将是空列表。

于 2012-01-17T05:56:45.480 回答