Как отсортировать N списков по общей сумме элементов каждого списка с помощью Mathematica? - PullRequest
3 голосов
/ 17 января 2012

Учитывая список, содержащий k подсписки, пусть A={{a1,a2,a3,...},{b1,b2,b3,...},...}, я хочу отсортировать эти списки по их Total[A[i]]. Есть ли эффективный способ сделать это?

Ответы [ 3 ]

8 голосов
/ 17 января 2012

Отметьте SortBy в документации для диапазона возможностей сортировки списков списков.

 SortBy[A,Total]

дает то, что вам нужно.

РЕДАКТИРОВАТЬ: В соответствии с комментарием г-на Wizard ниже и объяснение в ссылке,

SortBy[A,{Total}]

лучше.

4 голосов
/ 17 января 2012

Обратите внимание, что во многих случаях сортировка на основе Ordering может выполняться быстрее, чем SortBy, поскольку она позволяет использовать векторизацию. В данном конкретном случае ускорение не так велико:

In[50]:= test = RandomInteger[10,{5000000,5}];

In[54]:= (res1=SortBy[test,{Total}]);//Timing
(res2 = test[[Ordering[Total[test,{2}]]]]);//Timing
res1===res2

Out[54]= {1.422,Null}
Out[55]= {1.125,Null}
Out[56]= True

Но это потому, что Total является встроенной функцией. Единственная причина, по которой был введен SortBy, - это эффективность (то есть для одной функции сравнения. Для нескольких функций сравнения в качестве прерывателей связи также удобство). Это более эффективно, чем Sort, потому что это более конкретно, и, следовательно, обходит больше шагов в основной последовательности оценки. Тем не менее, SortBy не может использовать возможную возможность отображения (векторизованный характер) функции, на которой основана сортировка, - она ​​применяется к элементам списка один за другим. Решение с упорядочением явно использует возможность полного вычисления функции сортировки (в этом случае Total[#,{2}]& делает это), и, следовательно, быстрее.

Если, например, задача будет состоять в сортировке по сумме второго, третьего и четвертого элемента в каждом подсписке, мы увидим большую разницу в производительности:

In[60]:= (res3=SortBy[test,{Total[#[[2;;4]]]&}]);//Timing
(res4=test[[Ordering[Total[test[[All,2;;4]],{2}]]]]);//Timing
res3==res4

Out[60]= {2.39,Null}
Out[61]= {1.11,Null}
Out[62]= True

Как правило, повышение производительности будет наибольшим для функций сортировки, которые требуют значительных вычислительных затрат и векторизации, и поэтому они намного быстрее при применении ко всему списку. Обратите внимание, однако, что повышение производительности для сортировки никогда не будет таким большим, как для самой функции сортировки, для больших списков. Это происходит из-за внутренней сложности сортировки, которая пропорциональна n*Log[n] для больших списков длиной n, и эта сложность всегда будет там.

0 голосов
/ 17 января 2012

Следующее должно работать (но я не могу проверить это прямо сейчас):

Sort[A, Total[#1]<Total[#2]&]
...