2013-03-06 54 views
0

因此,我對Mathematica非常陌生,並且正在努力學習以功能性方式解決問題。我正在解決的問題是列出我可以從列表中總結元素的方式(帶有重複),因此總和等於某個值。下面的代碼解決了這個問題。Mathematica中的切削工具的變體

i = {7.25, 7.75, 15, 19, 22}; 
m = 22; 
getSum[l_List, n_List] := Total[Thread[{l, n}] /. {x_, y_} -> x y]; 
t = Prepend[Map[Range[0, Floor[m/#]] &, i], List]; 
Outer @@ %; 
Flatten[%, ArrayDepth[%] - 2]; 
Map[{#, getSum[i, #]} &, %]; 
DeleteCases[%, {_, x_} /; x > m || x == 0]; 
TableForm[Flatten /@ SortBy[%, Last], 0, 
TableHeadings -> {None, Append[i, "Total"]}] 

但是,代碼檢查了很多不必要的情況,如果m高於列表的較長時間,這可能是一個問題。我的問題僅僅是解決這個問題的最具Mathematica式的方式,涉及效率和代碼優化。

+3

在這裏和Mathematica.StackExchange上交叉發佈沒有多大意義 - 兩個地方大多數人是同一個人,只有大部分人轉向那個人。 – 2013-03-06 12:08:35

回答

1

一個簡單的,雖然不是最佳的方法是:

sol = Reduce[Dot[i, {a, b, c, d, e}] <= m, {a, b, c, d, e}, Integers]; 

在第一次嘗試用較小的i,說i = {7.25, 7.75}得到一個關於你是否可以用這種感覺。

可以通過提供上限爲係數,像

sol = Reduce[And @@ {Dot[i, {a, b, c, d, e}] <= m, 
        Sequence @@ Thread[{a, b, c, d, e} <= Quotient[m, i]]}, 
     {a, b, c, d, e}, Integers] 
+1

我會upvote,但你的總代表現在看起來好多了,比添加了10個更好。 – 2013-03-06 10:37:15

+0

@HighPerformanceMark我必須同意,我會接受精神上的支持。 – 2013-03-06 10:39:21

+0

確實非常整齊的代碼!然而,與我的解決方案相比,它似乎非常慢,這正是我想要改進的地方! – maestron 2013-03-06 11:36:24

0

如何

recurr[numbers_, boundary_] := 

    Reap[memoryRecurr[0, {}, numbers, boundary]][[2, 1]]; 

memoryRecurr[_, _, {}, _] := Null; 

memoryRecurr[sum_, numbers_, restNumbers_, diff_] := 
    (
    Block[ 
    {presentNumber = First[restNumbers], restRest = Rest[restNumbers]} 
    , 
    If[ 
     presentNumber <= diff 
     , 
     Block[{ 
     newNumbers = Append[numbers, presentNumber], 
     newSum = sum + presentNumber 
     }, 
     Sow[{newNumbers, newSum}]; 

     memoryRecurr[ 
     newSum, 
     newNumbers, 
     restRest, 
     diff - presentNumber 
     ]; 
     ] 
     ]; 
    memoryRecurr[sum, numbers, restRest, diff] 
    ]; 

    ); 

這樣

recurr[{1, 2, 3, 4, 5}, 7] 

提高速度 - >

{{{1}, 1}, {{1, 2}, 3}, {{1, 2, 3}, 6}, {{1, 2, 4}, 7}, {{1, 3}, 
    4}, {{1, 4}, 5}, {{1, 5}, 6}, {{2}, 2}, {{2, 3}, 5}, {{2, 4}, 
    6}, {{2, 5}, 7}, {{3}, 3}, {{3, 4}, 7}, {{4}, 4}, {{5}, 5}}