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_conjunct2(SuppliersNew,field,perc,fval_ottimale,GuadagnoAlPezzo,TimeToMarket,VenditaMercato,x_ottimale,Demand,ValueTarget,SuppliersOriginal)
function [PayoffScenario,quanto,impatto,aggiuntivo,outofChainIndex,outofChainDemand,PayoffVariations,costfake] = Payoff_SCRS_conjunct2(SuppliersNew,field,perc,fval_ottimale,GuadagnoAlPezzo,TimeToMarket,VenditaMercato,x_ottimale,Demand,ValueTarget,SuppliersOriginal)

if not(isfield(SuppliersNew(1),field))
    disp('error')
end   


SuppliersOld=SuppliersNew;
SuppliersNew=SuppliersOriginal;

costfake=zeros(1,length(SuppliersNew));
%disp('Payoff computation');
outofChainIndex=[];
outofChainDemand=[];
PayoffScenario=[getfield(SuppliersNew(1),field),x_ottimale'];
aggiuntivo=[];

if strcmp(field,'LeadTime')
    passo=0.25;
else
    passo=1;
end    

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))+1;
    % 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;
    %il round  pericoloso
    PayoffVariations=struct('Plot',[]);
    
    for minus=inizio:passo:round(variazione)
            
             %faccio variare il parametro che passo
             SuppliersNew2(i)=setfield(SuppliersNew2(i),field,(getfield(SuppliersNew(i),field)-minus));
             % vedo come impatta sulla capacit produttiva originale
             % se non vario il leadtime resta la stessa
             ProdCapFake= (SuppliersNew(i).ProdCap*SuppliersNew(i).LeadTime)/SuppliersNew2(i).LeadTime;
             %ProdCapFake=(SuppliersNew(i).ProdCap/SuppliersNew(i).LeadTime)*SuppliersNew2(i).LeadTime;
             
             %valuto il costo finale che ne deriva dalla variazione se 
             %lead time non devo inserirlo ma solo usarlo
             if strcmp(field,'LeadTime')
                CostFake=round(SuppliersNew(i).UnitFixedCost+((double(SuppliersNew(i).ProdCap)/double(ProdCapFake))*(SuppliersNew(i).UnitProdCost-SuppliersNew(i).UnitFixedCost)));
             else
                CostFake=round(SuppliersNew(i).UnitFixedCost+((double(SuppliersNew(i).ProdCap)/double(SuppliersNew2(i).ProdCap))*(SuppliersNew(i).UnitProdCost-SuppliersNew(i).UnitFixedCost)));
             end
             SuppliersNew2(i).UnitProdCost=CostFake;
                                 
             if ((SuppliersNew2(i).UnitProdCost-SuppliersNew(i).UnitFixedCost)<=0)
                 % impossibile dichiarare un prezzo di vendita
                 %inferiore ai costi fissi
                 break;
             end  
             % uso la versione con le variazioni sul costo e sul parametro
             % per valutare la rete
             [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      
             
             %faccio variare il parametro che passo
             SuppliersNew2(i)=setfield(SuppliersNew2(i),field,(getfield(SuppliersNew(i),field)+minus));
             % vedo come impatta sulla capacit produttiva originale
             % se non vario il leadtime resta la stessa
             ProdCapFake= (SuppliersNew(i).ProdCap*SuppliersNew(i).LeadTime)/SuppliersNew2(i).LeadTime;
             %ProdCapFake=(SuppliersNew(i).ProdCap/SuppliersNew(i).LeadTime)*SuppliersNew2(i).LeadTime;
             
             %valuto il costo finale che ne deriva dalla variazione se 
             %lead time non devo inserirlo ma solo usarlo
             if strcmp(field,'LeadTime')
                CostFake=round(SuppliersNew(i).UnitFixedCost+((SuppliersNew(i).ProdCap/ProdCapFake)*(SuppliersNew(i).UnitProdCost-SuppliersNew(i).UnitFixedCost)));
             else
                CostFake=round(SuppliersNew(i).UnitFixedCost+((double(SuppliersNew(i).ProdCap)/double(SuppliersNew2(i).ProdCap))*(SuppliersNew(i).UnitProdCost-SuppliersNew(i).UnitFixedCost)));
             end
             SuppliersNew2(i).UnitProdCost=CostFake;
             
             if ((SuppliersNew2(i).UnitProdCost-SuppliersNew(i).UnitFixedCost)<=0)
                 % impossibile dichiarare un prezzo di vendita
                 %inferiore ai costi fissi
                 break;
             end  
             % uso la versione con le variazioni sul costo e sul parametro
             % per valutare la rete
             [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
     
        if (x(i)>SuppliersNew(i).ProdCap)
            aggiuntivo(i)=GuadagnoAlPezzo*(x(i)-uint32(round( min(((SupplierFake.UnitProdCost)*SuppliersNew(i).ProdCap)/(SuppliersNew(i).UnitProdCost), (SuppliersNew(i).ProdCap/SuppliersNew(i).LeadTime)*SupplierFake.LeadTime ))));
        else
            %il danno per la rete  il numero di pezzi che non riesco a
            %fare ovvero il numero di pezzi assegnati - (minimo tra (il numero di pezzi che riesco a fare con i soldi, il numero di pezzi che faccio nel tempo))
            %se il tempo non varia  la capacit produttiva che dichiaro
            aggiuntivo(i)=GuadagnoAlPezzo*(x(i)-uint32(round( min(((SupplierFake.UnitProdCost)*x(i))/(SuppliersNew(i).UnitProdCost), (SuppliersNew(i).ProdCap/SuppliersNew(i).LeadTime)*SupplierFake.LeadTime ))));
        end
        if (valore>0)
           % se ho trovato qualche cosa di sensato 
           PayoffScenario=[PayoffScenario;fakevalue,x'];
           costfake(i)=SupplierFake.UnitProdCost; 
        else
           PayoffScenario=[PayoffScenario;getfield(SuppliersNew(i),field),x'];
        end
     end   
end  

Contact us at files@mathworks.com