function centralAssignmentABC
%% assegnazione centralizzata dei task con algoritmo di ottimizzazione lineare
%Restituisce la nuova configurazione di assegnazione agli agenti ed il
%profitto da essa derivante (che e' stato massimizzato).
 
global pool X t alpha V;
   
%% Procedura di assegnazione
    
    %Nuova procedura di assegnazione e' subordinata (nel main) all'arrivo di nuovi task
    %oppure all'esaurimento di qualcuno di essi.
    
    L = length(pool); 
    N = length(X);
    C = zeros(N,L);
    for i=1:N
        for j=1:L
            if (find(X(i).v == pool(j).loc))
                %calcolo numero degli agenti che possono svolgere il task j
                %profitto nell'associare all'agente i il task j 
                C(i,j) = alpha*(pool(j).pr) +...
                            (1-alpha)*(t-pool(j).Tocc)/pool(j).Tdrop; 

            else
                C(i,j)=-1000000; % notazione Big-M per -\infty
            end
        end
    end
    %Costruzione matrice dei vincoli A
    %Le variabili decisionali sono tutte le possibili x_{ij}, che sono N*L
    % x_{i,j} = 1 se agente i svolge task j
    A1 = zeros(N,N*L); %al massimo un task per agente
    A2 = zeros(L,N*L); %al massimo un agente per task
    for i=1:N
        A1(i,:) = [zeros(1,(i-1)*L) ones(1,L) zeros(1,(N-i)*L)];
    end
    for i=1:N
        A2(:,(i-1)*L+1:i*L) = eye(L);
    end
    Aopt = [A1;A2];
    %Costruzione del vettore dei termini noti
    b = ones(N+L,1);
    %Vettore dei coefficienti della funzione obiettivo: 
    % max f = - min -f
    f = zeros(1,N*L);
    for i=1:N
        f(1,(i-1)*L+1:i*L)=-C(i,:);
    end
    lb = zeros(N*L,1);
    ub = ones(N*L,1);
    %Soluzione del problema di programmazione lineare: formulazione TUM
    %permette di evitare l'introduzione di vincoli di interezza
    options = optimset('LargeScale', 'off', 'Simplex', 'on');
    [x,fval,exitflag,output] = linprog(f',Aopt,b,[],[],lb,ub,[],options);
    maxF=-fval;
    %Adeguamento della situazione degli agenti: NB il pool contiene tutti i
    %task sussistenti, anche quelli in esecuzione presso gli agenti (necessario per l'ottimizzazione)
    %ind = find(x); %associazioni agente/task selezionate
    matInd = zeros(N,L);
    for i=1:N
        matInd(i,:)=x((i-1)*L+1:i*L);
    end
    [i,j]= find(matInd); %i vettore agenti attivi, j vettore task assegnati
    for ii=1:N
        if (not(isempty(X(ii).tsk)))
                  %Agente preventivamente scaricato
                  X(ii).tsk.a=0;
                  pool(find(X(ii).tsk.ID==[pool.ID])).a=0;
                  X(ii).tsk=[];      
        end
    end   
    for ii=1:N   
        if find(i==ii)
            %Agente assegnato ad un task
            message(['Task ',num2str(pool(j(find(i==ii))).ID),' assegnato ad agente ',num2str(ii)])
            X(ii).tsk=pool(j(find(i==ii)));
            X(ii).tsk.a=ii;
            pool(j(find(i==ii))).a=ii;
        end
    end
end
