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_conjunct(SuppliersNew,0.5,fval_ottimale,GuadagnoAlPezzo,TimeToMarket,VenditaMercato,x_ottimale,Demand)
function [PayoffScenario,quanto,impatto,aggiuntivo,outofChainIndex,outofChainDemand] = Payoff_SCRS_conjunct(SuppliersNew,0.5,fval_ottimale,GuadagnoAlPezzo,TimeToMarket,VenditaMercato,x_ottimale,Demand)

disp('Payoff computation');
outofChainIndex=[];
outofChainDemand=[];
% mi salvo anche i vari scenari che si generano tenendo le allocazioni x e
% il mio valore di costo di produzione
PayoffScenario=[];
ActiveSuppliers=[1:1:length(SuppliersNew)]
for i=1:1:length(ActiveSuppliers)
    competitors=0;
   for j=1:1:length(SuppliersNew)
         if (ActiveSuppliers(i)==j)
             competitors(j)=0;
             continue;
         end    
         %  competitor se ho la stessa coppia di indici in Suppliers.
         % ed ovviamente sono dello stesso livello
         if (strcmp(SuppliersNew(j).Product,SuppliersNew(ActiveSuppliers(i)).Product))
             for k=1:2:length(SuppliersNew(j).Suppliers)
                 coppia=SuppliersNew(j).Suppliers(k:k+1);
                 for h=1:2:length(SuppliersNew(ActiveSuppliers(i)).Suppliers)
                     if (sum(coppia==SuppliersNew(ActiveSuppliers(i)).Suppliers(h:h+1))==2)
                         competitors(j)=1;
                     end
                 end
             end
         end             
   end
   % se non ho competitors allora ho payoff massimo perch posso sperare di
   % guadagnarci di pi perch il mio prezzo  l'unico
   % questo non vale con la cap coru
   if (sum(competitors==1)==0)
       % imposed as maximum
       quanto(i)=10000000;
       PayoffScenario=[PayoffScenario;SuppliersNew(ActiveSuppliers(i)).UnitProdCost,SuppliersNew(ActiveSuppliers(i)).ProdCap,x_ottimale'];
   else
         % altrimenti devo vedere quanto posso aspettarmi di guadagnare
         compindex=find(competitors==1);
         competirorsprices=[];
         competirorspricesDemand=[];
         competirorLowersprices=[];
         competirorLowerspricesDemand=[];
         for k=1:1:length(compindex)
             % guardo il prezzo dei competitors che sono nella rete e
             % segno chi ha il prezzo pi alto e pi basso
             if (SuppliersNew(compindex(k)).UnitProdCost>=SuppliersNew(ActiveSuppliers(i)).UnitProdCost)
                   competirorsprices=[competirorsprices,SuppliersNew(compindex(k)).UnitProdCost];
                   if (SuppliersNew(compindex(k)).Demand>0) %se  nella catena lo metto altrimenti no
                       competirorspricesDemand=[competirorspricesDemand,1];
                   else
                       competirorspricesDemand=[competirorspricesDemand,0];
                   end    
             else   
                   % fuori dalla catena non  possibile con prezzo basso ma potrebbe anche esserlo per altre questioni tipo il tempo
                   competirorLowersprices=[competirorLowersprices,SuppliersNew(compindex(k)).UnitProdCost];
                   if (SuppliersNew(compindex(k)).Demand>0) %se  nella catena lo metto altrimenti no
                       competirorLowerspricesDemand=[competirorLowerspricesDemand,1];
                   else
                       competirorLowerspricesDemand=[competirorLowerspricesDemand,0];
                   end    
             end
         end
         % ho preso i prezzi dei competitor che sono nella catena sia i pi alti che i pi bassi
         % esistono competitors nella catena con prezzi pi alti?
         if max(competirorsprices.*competirorspricesDemand)
            %c' qualche competitor pi caro, se sono nella catena allora
            if (SuppliersNew(ActiveSuppliers(i)).Demand>0)
               %#################################### 
               SuppliersNew2=SuppliersNew;
               valore=SuppliersNew2(ActiveSuppliers(i)).Demand*SuppliersNew(ActiveSuppliers(i)).UnitProdCost;
               unitprodcost=0;
               prodcap=0;
               
               exitflag=2;
               for minus=1:1:(max(competirorsprices.*competirorspricesDemand)-SuppliersNew(ActiveSuppliers(i)).UnitProdCost)
                       %Questo  il prezzo targhet
                       SuppliersNew2(ActiveSuppliers(i)).UnitProdCost=(max(competirorsprices.*competirorspricesDemand)-minus);
                       %Significa avere la capacit produttiva fake
                       
                       if ((SuppliersNew2(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost)<=0)
                          % impossibile dichiarare un prezzo di vendita
                          %inferiore ai costi fissi
                          break;
                       end  
                       
                       prodFake=round(((SuppliersNew(ActiveSuppliers(i)).ProdCap)*(SuppliersNew(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost))/(SuppliersNew2(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost));
                       SuppliersNew2(ActiveSuppliers(i)).ProdCap=prodFake;
                       
                       [xaux,exitflagaux,fvalaux] = Simplex_SCRS(SuppliersNew2,TimeToMarket,VenditaMercato);
                       if ((xaux(ActiveSuppliers(i))*SuppliersNew2(ActiveSuppliers(i)).UnitProdCost)>=valore)
                           valore=(xaux(ActiveSuppliers(i))*SuppliersNew2(ActiveSuppliers(i)).UnitProdCost);
                           x=xaux;
                           exitflag=exitflagaux;
                           fval=fvalaux;
                           unitprodcost=SuppliersNew2(ActiveSuppliers(i)).UnitProdCost;
                           prodcap=SuppliersNew2(ActiveSuppliers(i)).ProdCap;
                       end 
                       %if ((xaux(ActiveSuppliers(i))==Demand)|(xaux(ActiveSuppliers(i))==SuppliersNew2(ActiveSuppliers(i)).ProdCap))
                       %    break;
                       %end    
               end
               if (exitflag==2)
                       %non ho mai trovato un valore migliore del mio attuale
                       quanto(i)=0;
                       impatto(i)=0;
                       PayoffScenario=[PayoffScenario;SuppliersNew(ActiveSuppliers(i)).UnitProdCost,SuppliersNew(ActiveSuppliers(i)).ProdCap,x_ottimale'];
                       continue;
               end    
               if not(exitflag==1)
                  disp('error computing simplex')
                  continue;
               else
                  quanto(i)=((unitprodcost)-(SuppliersNew(ActiveSuppliers(i)).UnitProdCost))*x(ActiveSuppliers(i));
                  impatto(i)=fval-fval_ottimale;
                  if (valore>0)
                      % se ho trovato qualche cosa di sensato 
                      PayoffScenario=[PayoffScenario;unitprodcost,prodcap,x'];
                   else
                      PayoffScenario=[PayoffScenario;SuppliersNew(ActiveSuppliers(i)).UnitProdCost,SuppliersNew(ActiveSuppliers(i)).ProdCap,x'];
                   end
               end
            else
                %###################### FUORI CATENA NONOSTANTE PREZZI INFERIORI###############
                % abbasso il mio prezzo nella speranza di ottenere qualche
                % cosa ma  difficile
                outofChainIndex=[outofChainIndex,i];
                SuppliersNew2=SuppliersNew;
                valore=SuppliersNew2(ActiveSuppliers(i)).Demand*SuppliersNew(ActiveSuppliers(i)).UnitProdCost;
                unitprodcost=0;
                prodcap=0;
                exitflag=2;
                for minus=1:1:(SuppliersNew(ActiveSuppliers(i)).UnitProdCost-1)
                       SuppliersNew2(ActiveSuppliers(i)).UnitProdCost=SuppliersNew(ActiveSuppliers(i)).UnitProdCost-minus;
                       
                       %Significa avere la capacit produttiva fake
                       
                       if ((SuppliersNew2(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost)<=0)
                          % impossibile dichiarare un prezzo di vendita
                          %inferiore ai costi fissi
                          break;
                       end  
                       
                       prodFake=round(((SuppliersNew(ActiveSuppliers(i)).ProdCap)*(SuppliersNew(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost))/(SuppliersNew2(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost));
                       SuppliersNew2(ActiveSuppliers(i)).ProdCap=prodFake;
                       
                       [xaux,exitflagaux,fvalaux] = Simplex_SCRS(SuppliersNew2,TimeToMarket,VenditaMercato);
                       if ((xaux(ActiveSuppliers(i))*SuppliersNew2(ActiveSuppliers(i)).UnitProdCost)>=valore)
                           valore=(xaux(ActiveSuppliers(i))*SuppliersNew2(ActiveSuppliers(i)).UnitProdCost);
                           x=xaux;
                           exitflag=exitflagaux;
                           fval=fvalaux;
                           unitprodcost=SuppliersNew2(ActiveSuppliers(i)).UnitProdCost;
                           prodcap=SuppliersNew2(ActiveSuppliers(i)).ProdCap;
                       end 
                       %if ((xaux(ActiveSuppliers(i))==Demand)|(xaux(ActiveSuppliers(i))==SuppliersNew2(ActiveSuppliers(i)).ProdCap))
                       %    break;
                       %end    
                end
                if (exitflag==2)
                       %non ho mai trovato un valore migliore del mio attuale
                       quanto(i)=0;
                       impatto(i)=0;
                       PayoffScenario=[PayoffScenario;SuppliersNew(ActiveSuppliers(i)).UnitProdCost,SuppliersNew(ActiveSuppliers(i)).ProdCap,x_ottimale'];
                       continue;
                end    
                if not(exitflag==1)
                  disp('error computing simplex')
                  continue;
                else
                  quanto(i)=(unitprodcost)*x(ActiveSuppliers(i));
                  aggiuntivo(i)=GuadagnoAlPezzo*(x(ActiveSuppliers(i))-round(((unitprodcost)*x(ActiveSuppliers(i)))/(SuppliersNew(ActiveSuppliers(i)).UnitProdCost)));
                  %aggiuntivo(i)=((SuppliersNew(ActiveSuppliers(i)).UnitProdCost)-(unitprodcost))*x(ActiveSuppliers(i));
                  impatto(i)=fval-fval_ottimale;
                  if (valore>0)
                      % se ho trovato qualche cosa di sensato 
                      PayoffScenario=[PayoffScenario;unitprodcost,prodcap,x'];
                  else
                      PayoffScenario=[PayoffScenario;SuppliersNew(ActiveSuppliers(i)).UnitProdCost,SuppliersNew(ActiveSuppliers(i)).ProdCap,x'];
                  end
                  outofChainDemand=[outofChainDemand,min(SuppliersNew(ActiveSuppliers(i)).ProdCap,Demand)];
                end 
                
            end  
            
         else
            %non ho competitors con prezzi pi alti, ne esistono con prezzi pi bassi? 
            if max(competirorLowersprices.*competirorLowerspricesDemand) 
              if (SuppliersNew(ActiveSuppliers(i)).Demand>0)
                
                   %############# ABBASSO IL MIO PREZZO VERSO IL COMPETITOR###########
                   SuppliersNew2=SuppliersNew;
                   valore=SuppliersNew2(ActiveSuppliers(i)).Demand*SuppliersNew(ActiveSuppliers(i)).UnitProdCost;
                   unitprodcost=0;
                   prodcap=0;
                   exitflag=2;
                   for minus=1:1:(((SuppliersNew(ActiveSuppliers(i)).UnitProdCost)-(min(competirorLowersprices(find(competirorLowersprices.*competirorLowerspricesDemand)))))-1)
                       SuppliersNew2(ActiveSuppliers(i)).UnitProdCost=SuppliersNew(ActiveSuppliers(i)).UnitProdCost-minus;
                       
                       if ((SuppliersNew2(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost)<=0)
                          % impossibile dichiarare un prezzo di vendita
                          %inferiore ai costi fissi
                          break;
                       end  
                       
                       prodFake=round(((SuppliersNew(ActiveSuppliers(i)).ProdCap)*(SuppliersNew(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost))/(SuppliersNew2(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost));
                       SuppliersNew2(ActiveSuppliers(i)).ProdCap=prodFake;
                       
                       [xaux,exitflagaux,fvalaux] = Simplex_SCRS(SuppliersNew2,TimeToMarket,VenditaMercato);
                       if ((xaux(ActiveSuppliers(i))*SuppliersNew2(ActiveSuppliers(i)).UnitProdCost)>=valore)
                           valore=(xaux(ActiveSuppliers(i))*SuppliersNew2(ActiveSuppliers(i)).UnitProdCost);
                           x=xaux;
                           exitflag=exitflagaux;
                           fval=fvalaux;
                           unitprodcost=SuppliersNew2(ActiveSuppliers(i)).UnitProdCost;
                           prodcap=SuppliersNew2(ActiveSuppliers(i)).ProdCap;
                       end 
                       if ((xaux(ActiveSuppliers(i))==Demand)|(xaux(ActiveSuppliers(i))==SuppliersNew2(ActiveSuppliers(i)).ProdCap))
                           break;
                       end    
                   end
                   if (exitflag==2)
                       %non ho mai trovato un valore migliore del mio attuale
                       quanto(i)=0;
                       impatto(i)=0;
                       PayoffScenario=[PayoffScenario;SuppliersNew(ActiveSuppliers(i)).UnitProdCost,SuppliersNew(ActiveSuppliers(i)).ProdCap,x_ottimale'];
                       continue;
                   end    
                   if not(exitflag==1)
                      disp('error computing simplex')
                      continue;
                   else           
                       
                   quanto(i)=((unitprodcost)*x(ActiveSuppliers(i)))-(SuppliersNew(ActiveSuppliers(i)).UnitProdCost)*SuppliersNew(ActiveSuppliers(i)).Demand;
                   aggiuntivo(i)=GuadagnoAlPezzo*(x(ActiveSuppliers(i))-round(((unitprodcost)*x(ActiveSuppliers(i)))/(SuppliersNew(ActiveSuppliers(i)).UnitProdCost)));
                   impatto(i)=fval-fval_ottimale;
                   
                   if (valore>0)
                      % se ho trovato qualche cosa di sensato 
                      PayoffScenario=[PayoffScenario;unitprodcost,prodcap,x'];
                   else
                      PayoffScenario=[PayoffScenario;SuppliersNew(ActiveSuppliers(i)).UnitProdCost,SuppliersNew(ActiveSuppliers(i)).ProdCap,x'];
                   end
                   end
                  
                  
              else
                %############ FUORI DALLA CATENA ABBASSO AL MINIMO E CERCO  
                outofChainIndex=[outofChainIndex,i];
                SuppliersNew2=SuppliersNew;
                valore=SuppliersNew2(ActiveSuppliers(i)).Demand*SuppliersNew(ActiveSuppliers(i)).UnitProdCost;
                unitprodcost=0;
                prodcap=0;
                
                exitflag=2;
                for minus=1:1:((min(competirorLowersprices(find(competirorLowersprices.*competirorLowerspricesDemand))))-1)
                       SuppliersNew2(ActiveSuppliers(i)).UnitProdCost=(min(competirorLowersprices(find(competirorLowersprices.*competirorLowerspricesDemand)))-minus);
                       %Significa avere la capacit produttiva fake
                       if ((SuppliersNew2(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost)<=0)
                          % impossibile dichiarare un prezzo di vendita
                          %inferiore ai costi fissi
                          break;
                       end    
                       prodFake=round(((SuppliersNew(ActiveSuppliers(i)).ProdCap)*(SuppliersNew(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost))/(SuppliersNew2(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost));
                       SuppliersNew2(ActiveSuppliers(i)).ProdCap=prodFake;       
                       
                       [xaux,exitflagaux,fvalaux] = Simplex_SCRS(SuppliersNew2,TimeToMarket,VenditaMercato);
                       if ((xaux(ActiveSuppliers(i))*SuppliersNew2(ActiveSuppliers(i)).UnitProdCost)>=valore)
                           valore=(xaux(ActiveSuppliers(i))*SuppliersNew2(ActiveSuppliers(i)).UnitProdCost);
                           x=xaux;
                           exitflag=exitflagaux;
                           fval=fvalaux;
                           unitprodcost=SuppliersNew2(ActiveSuppliers(i)).UnitProdCost;
                           prodcap=SuppliersNew2(ActiveSuppliers(i)).ProdCap;
                       end 
                       if ((xaux(ActiveSuppliers(i))==Demand)|(xaux(ActiveSuppliers(i))==SuppliersNew2(ActiveSuppliers(i)).ProdCap))
                           break;
                       end    
                end
                if (exitflag==2)
                       %non ho mai trovato un valore migliore del mio attuale
                       quanto(i)=0;
                       impatto(i)=0;
                       PayoffScenario=[PayoffScenario;SuppliersNew(ActiveSuppliers(i)).UnitProdCost,SuppliersNew(ActiveSuppliers(i)).ProdCap,x_ottimale'];
                       continue;
                end
                if not(exitflag==1)
                   disp('error computing simplex')
                   continue;
                else
                   quanto(i)=(unitprodcost)*x(ActiveSuppliers(i));
                   % far pagare alla catena il danno di non consegare i
                   % pezzi perch ho barato sulla capacita produttiva                    
                   aggiuntivo(i)=GuadagnoAlPezzo*(x(ActiveSuppliers(i))-round(((unitprodcost)*x(ActiveSuppliers(i)))/(SuppliersNew(ActiveSuppliers(i)).UnitProdCost)));
                   impatto(i)=fval-fval_ottimale;
                   if (valore>0)
                      % se ho trovato qualche cosa di sensato 
                      PayoffScenario=[PayoffScenario;unitprodcost,prodcap,x'];
                   else
                      PayoffScenario=[PayoffScenario;SuppliersNew(ActiveSuppliers(i)).UnitProdCost,SuppliersNew(ActiveSuppliers(i)).ProdCap,x'];
                   end
                   outofChainDemand=[outofChainDemand,min(SuppliersNew(ActiveSuppliers(i)).ProdCap,Demand)];
                end
                
              end
            else
                %################ NON HO COMPETITORS DENTRO LA CHAIN MA NE HO FUORI######
                if (SuppliersNew(ActiveSuppliers(i)).Demand>0)
                   SuppliersNew2=SuppliersNew;
                   valore=SuppliersNew2(ActiveSuppliers(i)).Demand*SuppliersNew(ActiveSuppliers(i)).UnitProdCost;
                   unitprodcost=0;
                   prodcap=0;
                   
                   exitflag=2;
                   for minus=1:1:(min(competirorsprices)-SuppliersNew(ActiveSuppliers(i)).UnitProdCost)
                              
                       SuppliersNew2(ActiveSuppliers(i)).UnitProdCost=(min(competirorsprices)-minus);
                       
                       if ((SuppliersNew2(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost)<=0)
                          % impossibile dichiarare un prezzo di vendita
                          %inferiore ai costi fissi
                          break;
                       end  
                       
                       prodFake=round(((SuppliersNew(ActiveSuppliers(i)).ProdCap)*(SuppliersNew(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost))/(SuppliersNew2(ActiveSuppliers(i)).UnitProdCost-SuppliersNew(ActiveSuppliers(i)).UnitFixedCost));
                       SuppliersNew2(ActiveSuppliers(i)).ProdCap=prodFake; 
                       
                       [xaux,exitflagaux,fvalaux] = Simplex_SCRS(SuppliersNew2,TimeToMarket,VenditaMercato);
                       if ((xaux(ActiveSuppliers(i))*SuppliersNew2(ActiveSuppliers(i)).UnitProdCost)>=valore)
                           valore=(xaux(ActiveSuppliers(i))*SuppliersNew2(ActiveSuppliers(i)).UnitProdCost);
                           x=xaux;
                           exitflag=exitflagaux;
                           fval=fvalaux;
                           unitprodcost=SuppliersNew2(ActiveSuppliers(i)).UnitProdCost;
                           prodcap=SuppliersNew2(ActiveSuppliers(i)).ProdCap;
                       end 
                       if ((xaux(ActiveSuppliers(i))==Demand)|(xaux(ActiveSuppliers(i))==SuppliersNew2(ActiveSuppliers(i)).ProdCap))
                           break;
                       end    
                   end
                   if (exitflag==2)
                       %non ho mai trovato un valore migliore del mio attuale
                       quanto(i)=0;
                       impatto(i)=0;
                       PayoffScenario=[PayoffScenario;SuppliersNew(ActiveSuppliers(i)).UnitProdCost,SuppliersNew(ActiveSuppliers(i)).ProdCap,x_ottimale'];
                       continue;
                   end
                   if not(exitflag==1)
                      disp('error computing simplex')
                      continue;
                   else
                   quanto(i)=((unitprodcost)-(SuppliersNew(ActiveSuppliers(i)).UnitProdCost))*x(ActiveSuppliers(i));
                   impatto(i)=fval-fval_ottimale;
                   if (valore>0)
                      % se ho trovato qualche cosa di sensato 
                      PayoffScenario=[PayoffScenario;unitprodcost,prodcap,x'];
                   else
                      PayoffScenario=[PayoffScenario;SuppliersNew(ActiveSuppliers(i)).UnitProdCost,SuppliersNew(ActiveSuppliers(i)).ProdCap,x'];
                   end
                   end
                else
                    disp('Competitor set out of Chain')
                end    
            end 
         end
   end  
end

Contact us at files@mathworks.com