Pages: [1]   Go Down
Print
Author Topic: Esercizio sul fattoriale Factg  (Read 832 times)
0 Members e 1 Utente non registrato stanno visualizzando questa discussione.
rondey
Matricola
*
Offline Offline

Posts: 74


« on: 01-04-2016, 18:21:27 »

Code:
-module(factg).
-export([fg/2,loopAct/3,loopmanager/3]).

fg(G, N) ->
Manager = spawn(factg, loopmanager, [self(), 1, N+1]),
[spawn(factg, loopAct,[M, Manager, G]) || M <- lists:seq(0, N)],
receive
Result -> Result
end.

loopAct(N, Manager, G) ->
if (N==0) -> Manager ! G(1);
true  -> Manager ! G(N)
end.

loopmanager(PIDfather, Partial, NumValues) ->
if  (NumValues == 0) -> PIDfather!Partial;
true ->
receive
Result -> loopmanager(PIDfather, Partial * Result, NumValues - 1)
end
end.

Changelog:
  • Aggiunta di un end all'interno di loopmanager(potrebbe essere stato un mio errore di trascrizione...)
  • Aggiunto nel loopAct il caso in cui N=0(necessario perchè se come funzione G passo la funzione identità (G(N)=N) non otterrei la "classica" funzione fattoriale)

Attenzione: per utilizzare la funzione fg effettuare la seguente chiamata
Code:
fg(fun NOME_MODULO:NOME_FUNZIONE/NUMERO_ARGOMENTI, N).
dove NOME_FUNZIONE è il nome della funzione che si vuole applicare, NUMERO_ARGOMENTI è il numero di argomenti(arity) richiesti della funzione, NOME_MODULO è il nome del modulo che contiene la funzione.
Es:
Code:
factg:fg(fun math:sqrt/1, 50).
Logged
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 2.622



WWW
« Reply #1 on: 01-04-2016, 18:52:05 »

Bene.

Quote
    Aggiunto nel loopAct il caso in cui N=0(necessario perchè se come funzione G passo la funzione identità (G(N)=N) non otterrei la "classica" funzione fattoriale)

Dove sta scritto che la funzione deve corrispondere al fattoriale nel caso passiamo la funzione identita'?

Quello che dici e' piu' che ragionevole, ovviamente.

Voglio usare questo esempio solo per porre la vostra attenzione al seguente fatto:
quando bisogna implementare un programma occorre attenersi alla specifica.
La maggior parte delle volte non abbiamo idea del perche' il programma debba
funzionare come descritto dalla specifica.

Detto questo, ripeto che la tua osservazione e', nel presente contesto, estremamente ragionevole.

Un caro saluto
FB


Logged
rondey
Matricola
*
Offline Offline

Posts: 74


« Reply #2 on: 02-04-2016, 11:15:51 »

Credo che nel nostro caso specifico ce lo dica la consegna dell'esercizio:
Quote
Esercizio 2

Si consideri la seguente funzione Haskell
factg g 0 = g 1

factg g n = (g n)*(factg g (n-1))
Poiche' il calcolo di (g n) potrebbe richiedere tempo, vogliamo definire la stessa funzione in Erlang in modo che il calcolo di (g n) venga eseguito da un processo, mentre altri processi si occupano del calcolo di (factg g (n-1)).

Non vorrei dire una fesseria, ma mi pare di ricordare che lei ci aveva mostrato la consegna di questo esercizio, e sulla base di questa dovevamo effettuare la conversione parallelizzata a Erlang. In ogni caso io ho interpretato la richiesta del "factg g 0 = g 1" come una condizione voluta appositamente per poter ottenere il fattoriale nel caso del passaggio della funzione identità.
Logged
Ocelot92
Apprendista Forumista
**
Offline Offline

Posts: 301



« Reply #3 on: 02-04-2016, 15:07:03 »

Ecco la mia versione (senza list comprehension):
Code:
-module(factg).
-export([manager/3, inc/1, create/3, gworker/3, loop_manager/2, read_result/0, fg/2]).

%% Spawn a manager which will compute fg(N,G).
% Note: To spawn a manager with a g function use: fun Namefunction/Arity as
% parameter.
fg(N,G) ->
    spawn(factg, manager, [G, N, self()]),
    receive
        {factg, Result} ->
            Result
    end.

%% It creates the processes which will compute the G(N)s (the gworkers). Then it
%% waits for the received results and multiply them. Once it ends, the result is
%% send to the process who requested the computation (PIDClient).
manager (G,N,PIDClient) ->
    create(G,N,self()),
    Result = loop_manager((N + 1), 1),
    PIDClient ! {factg,Result}.

%% It spawns N+1 gworkers, passing to them the Manager's PID.
create(G,N,PIDMan) ->
    if
        N == 0 ->
            spawn(factg,gworker,[G,N,PIDMan]);
        true ->
            spawn(factg,gworker,[G,N,PIDMan]),
            create(G,N-1,PIDMan)
    end.

%% A gworker just send to the manager G(N).
gworker(G,N,PIDMan) ->
    PIDMan ! {gworker, G(N)}.

%% It waits for results from the gworkers and updates Result as the gworkers'
%% outputs are received. When all the gworkers ends, it returns Result.
loop_manager(Num_gworkers, Result) ->
    if
        Num_gworkers == 0 ->
            Result;
        true ->
            receive
                {gworker, GworkerOutput} ->
                    loop_manager(Num_gworkers - 1, GworkerOutput * Result);
                _ ->
                    loop_manager(Num_gworkers, Result)
            end
    end.

%% A simple test G.
inc(X) -> X + 1.


Updated: messa la funzione fg.
« Last Edit: 02-04-2016, 17:10:15 by Ocelot92 » Logged

I'm happy to tell you all that...
((λf.λx.f(f(x))) (λy.y^2)) (5)  = 5^4

"Si ma dillo che bisogna cliccare APPLY per crearle le partizioni…" - cit. Utente dopo aver seguito un How-To... .-.
Franco Barbanera
Moderator
Forumista Eroico
*****
Offline Offline

Posts: 2.622



WWW
« Reply #4 on: 02-04-2016, 16:26:38 »

Bene.

Pero', se stiamo implementando la funzione fg (o come la vogliamo chiamare)
dovrebbe esserci da qualche parte la definizione
fg(G,N) -> ...

Se volessi calcolare l'espressione (5* fg(inc,7)) +2
dvrei fare cose strane.

FB


Logged
Ocelot92
Apprendista Forumista
**
Offline Offline

Posts: 301



« Reply #5 on: 02-04-2016, 17:11:34 »

Bene.

Pero', se stiamo implementando la funzione fg (o come la vogliamo chiamare)
dovrebbe esserci da qualche parte la definizione
fg(G,N) -> ...

Se volessi calcolare l'espressione (5* fg(inc,7)) +2
dvrei fare cose strane.

FB

Giusto. Non avevo riletto l'esercizio.
Aggiornato.
Logged

I'm happy to tell you all that...
((λf.λx.f(f(x))) (λy.y^2)) (5)  = 5^4

"Si ma dillo che bisogna cliccare APPLY per crearle le partizioni…" - cit. Utente dopo aver seguito un How-To... .-.
Pages: [1]   Go Up
Print
Jump to: