0

だから私は 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 らしい方法は何であるかということです。

4

2 に答える 2

1

シンプルだが最適ではない方法の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]
于 2013-03-06T10:28:34.110 に答える
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}}
于 2013-03-07T18:47:11.333 に答える