Code covered by the BSD License  

Highlights from
Supply Chain Risk Simulator (SCRS)

from Supply Chain Risk Simulator (SCRS) by Marco Anisetti
Supply Chain simulator for risk assessment and incentive schemes.

Payoff_SCRS(SuppliersNew,field,perc,fval_ottimale,GuadagnoAlPezzo,TimeToMarket,VenditaMercato,x_ottimale,Demand,ValueTarget,SuppliersOriginal)
function [PayoffScenario,quanto,impatto,aggiuntivo,outofChainIndex,outofChainDemand,PayoffVariations] = Payoff_SCRS(SuppliersNew,field,perc,fval_ottimale,GuadagnoAlPezzo,TimeToMarket,VenditaMercato,x_ottimale,Demand,ValueTarget,SuppliersOriginal)

%ind incice del parametro di SuppierNew da far variare
%perc Percentuale di variazione
%direction se variazione positiva o negativa.
if not(isfield(SuppliersNew(1),field))
    disp('error')
end    

SuppliersOld=SuppliersNew;
SuppliersNew=SuppliersOriginal;

%disp('Payoff computation');
outofChainIndex=[];
outofChainDemand=[];
PayoffScenario=[getfield(SuppliersNew(1),field),x_ottimale'];
aggiuntivo=[];
PayoffVariations=struct('Plot',[]);

for i=2:1:length(SuppliersNew)
    % va fatto qua
    % vedo fino a quanto posso variare
    % se ho attaccato in suppliersNew avro il parametro di attacco che non 
    % quello effettivo. Con questo conto trovo la percentuale di attacco come
    % se fosse partendo da quello
    variazione=(getfield(SuppliersOld(i),field))*perc;
    inizio=(getfield(SuppliersOld(i),field)-getfield(SuppliersOriginal(i),field));
    % se ho attaccato questo significa devo comunque confrontarmi con la
    % situazione iniziale alla situazione iniziale
    if (SuppliersNew(i).Demand==0)
        outofChainIndex=[outofChainIndex,i];
        outofChainDemand=[outofChainDemand,min(SuppliersNew(i).ProdCap,Demand)];
    end    
        SuppliersNew2=SuppliersNew;
        valore=SuppliersNew2(i).Demand*SuppliersNew2(i).UnitProdCost;
        valoreInitial=valore;
        fakevalue=0;
        valoriPlot=[];       
        exitflag=2;
     for minus=inizio:1:round(variazione)
                  
             SuppliersNew2(i)=setfield(SuppliersNew2(i),field,(getfield(SuppliersNew(i),field)-minus));
             [xaux,exitflagaux,fvalaux] = Simplex_SCRS(SuppliersNew2,TimeToMarket,VenditaMercato);
             
             valoriPlot=[valoriPlot; (getfield(SuppliersNew(i),field)-minus),((xaux(i)*SuppliersNew2(i).UnitProdCost))-valoreInitial];
             if ((xaux(i)*SuppliersNew2(i).UnitProdCost)>valore)
                  valore=(xaux(i)*SuppliersNew2(i).UnitProdCost);
                  x=xaux;
                  exitflag=exitflagaux;
                  fval=fvalaux;
                  fakevalue=getfield(SuppliersNew2(i),field);
                  SupplierFake=SuppliersNew2(i);
             end 
   
             SuppliersNew2(i)=setfield(SuppliersNew2(i),field,(getfield(SuppliersNew(i),field)+minus));   
             [xaux,exitflagaux,fvalaux] = Simplex_SCRS(SuppliersNew2,TimeToMarket,VenditaMercato);
             
             valoriPlot=[valoriPlot; (getfield(SuppliersNew(i),field)+minus),((xaux(i)*SuppliersNew2(i).UnitProdCost))-valoreInitial];
             if ((xaux(i)*SuppliersNew2(i).UnitProdCost)>valore)
                  valore=(xaux(i)*SuppliersNew2(i).UnitProdCost);
                  x=xaux;
                  exitflag=exitflagaux;
                  fval=fvalaux;
                  fakevalue=getfield(SuppliersNew2(i),field);
                  SupplierFake=SuppliersNew2(i);
             end 
     end
     PayoffVariations(i).Plot= valoriPlot;
     
     if (exitflag==2)
        %non ho mai trovato un valore migliore del mio attuale
         quanto(i)=0;
         impatto(i)=0;
         PayoffScenario=[PayoffScenario;getfield(SuppliersNew(i),field),x_ottimale'];
         continue;
     end    
     if not(exitflag==1)
        disp('error computing simplex')
        continue;
     else
        % Il payoff  comunque tutto quello che porto a casa
        quanto(i)=valore-valoreInitial;
        % impatto sull'ottimo
        impatto(i)=fval-fval_ottimale;
        % ma poi se non riesco a produrlo ho l'impatto aggiuntivo
        % vedo se me ne vengono assegnate di pi della mia cap produttiva
        % calcolo quanto danno faccio
        % occhio che questo aggiuntivo deve stare anche nel vincolo di
        % tempo quindi non  cos semplice da calcolare
        % per ora visti i tempi e visto che la prima if non verrebbe mai
        % scelta se ho vincoli di tempo stringenti sistemo solo l'else
        
        if (x(i)>SuppliersNew(i).ProdCap)
            %questo  l'aggiuntivo normale ma bisogna tener presente i
            %tempi anche
            aggiuntivo(i)=GuadagnoAlPezzo*(x(i)-uint32(round(((SupplierFake.UnitProdCost)*SuppliersNew(i).ProdCap)/(SuppliersNew(i).UnitProdCost))));
        else
            aggiuntivo(i)=GuadagnoAlPezzo*uint32(x(i)-uint32(round(((SupplierFake.UnitProdCost)*x(i))/(SuppliersNew(i).UnitProdCost))));
            % assumo che la mia velocit di produzione sia quella
            % dichiarata all'inizio
            % SuppliersNew(i).LeadTime/SuppliersNew(i).ProdCap
            % guardo come verrebbe con la nuova allorazione e vedo quanti
            % pezzi non riesco a fare con quei tempi
            % questo vale solo se ho lead time stringenti, va rivisto
            % appena c' tempo
            aggiuntivo(i)= aggiuntivo(i)+GuadagnoAlPezzo*uint32(round((((SuppliersNew(i).LeadTime/SuppliersNew(i).ProdCap)-(SupplierFake.LeadTime/SupplierFake.ProdCap))*x(i))/(SuppliersNew(i).LeadTime/SuppliersNew(i).ProdCap)));
        end
        if (valore>0)
           % se ho trovato qualche cosa di sensato 
           PayoffScenario=[PayoffScenario;fakevalue,x'];
        else
           PayoffScenario=[PayoffScenario;getfield(SuppliersNew(i),field),x'];
        end
     end   
end  

Contact us at files@mathworks.com