Mathematica - funkcja rekurencyjna


(Grzelix) #1

Mam pewien problem z funckją rekurencyjną którą napisłem w Mathematice 8.0 i nie mogę doszukać się błędu. Co prawda w mathematice programować w mathematice dopiero zacząłem nie dawno i troche działam po omacku ale jak do tej pory jakoś wszystko mi działało.

Sprawa wygląda tak:

Poniżej kod z mathematici który wczytuje listy liczb i sprawdza ile jest możliwości że dwie listy nie mają wspólnego elementu (i tak do 3 listy)

czyli pierwsza z drugą i druga z trzecią w tym przypadku.

str = OpenRead["C:\\Users\\Krzysztof\\Documents\\out8.txt"];

l = {};

For[g = 0, g < 5, g++,

  s = Read[str, String];

  AppendTo[l, ReadList[StringToStream[s], Number]];

  ];


res = 0;

For[n = 1, n < 6, n++,

  sz[l[[n]], 1];

  ];

res;


sz[ll_, a_, z_] :=

  For[r = 1, r < 6, r++,

   q = l[[r]];

   If[Length[Intersection[ll, q]] == 0,

    If[a == 2, res++,sz[q, a + 1];];

    ];

   ];

plik wejściowy wygląda tak:

3 6

3 5 7

2 5 7

2 4 7

2 4 6

i na wyjściu powinno być 8 kombinacji natomiast dostaje tylko 7:

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

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

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

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

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

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

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

brakuje jeszcze kombinacji:

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

czekam na jakieś podpowiedzi bo mi samemu juz brakuje pomysłów co jest nie tak.


(Krystian Rosinski) #2

Nie wiem czy temat jest jeszcze aktualny. Wydaje mi się, że źle podchodzisz do programowania w Mathematice, bo fragment kodu który wkleiłeś przypomina raczej C.

W temacie wspominasz o funkcji rekurencyjnej. Rekurencja jest podstawową techniką wykorzystywaną w funkcyjnych językach programowania. Mathematica pozwala programować w sposób funkcyjny i często (a może zwykle) jest to najlepsze podejście do problemu. Posiada wiele funkcji (higher-order function) charakterystycznych dla funkcyjnych języków programowania jak np. Map, Fold, Thread itp. Poza tym podstawową strukturą danych w Mathematice jest lista (podobnie jak w Haskellu). Dlatego zacząłbym od importu danych w ten sposób:

In[1]:= data = Import["C:\\Users\\Krzysztof\\Documents\\out8.txt", "Table"]

Out[1]= {{3, 6}, {3, 5, 7}, {2, 5, 7}, {2, 4, 7}, {2, 4, 6}}

Najbardziej prymitywne rozwiązanie jakie mi przyszło do głowy to ,,wypisanie'' wszystkich możliwych trójek:

In[2]:= Permutations[data, {3}]

i wyrzucenie przypadków nie spełniających wymaganego warunku przy pomocy DeleteCases[expr, pattern]. Da się to pewnie zrobić w jednym kroku obliczeniowym.

Zwróć również uwagę na różnice pomiędzy Set (=), a SetDelayed (:=).