
#############################################################
#  procedure name: FUCOM-v1 by Huseyin Kocak 03/05/2020     #
#                                                           #
#############################################################
#  Step1 represents vector for Ranking of the Criteria      #
#  Step2 represent vector for comparison of Ranked Criteria #
#############################################################


FUCOM:=proc(Step1,Step2,ComparisonStyle)

local n,n1,i1,i2,abest,abest2,aworst,aworst2,nn1,nn2,nn3,nn4,i,best1,worst1,best2,worst2,sumBO,sumOW,sumBO2,sumOW2,sumw,sumw1,sol,CI,bob,bow,owb,oww,nn5,nn6,nn7,nn8,sumBOL,sumOWL,sumBO2L,sumOW2L,sol1,CI1,TD1,TD2,sumTD11,sumTD12,sumTD21,sumTD22;


#Step1:=readstat("please enter your Step1 vector as [.,.,.,.]");
#Step2:=readstat("please enter your Step2 vector as [.,.,.,.]");

## check the sizes of the vectors
n:=size(Step1,2);
n1:=size(Step2,2);
if abs(n-n1)>0 then error "sizes of Step1 and Step2 should be same and equal to number of criteria"; end if;


## Step2-a part
if ComparisonStyle=1 then
print("You are using the comparison vector in Step2-a");

if Step2[1]<>1 then error "the first element of Step2 should be 1"; end if;

# check ranking
for i from 1 to n do
if Step2[i]<1 then 
printf("\t\r The solution might be wrong! Please revise your Step2 comparison vector again because: %a",Step1[i]>Step1[i-1]); end if;
end do;

print("the number of the criteria",n1);

## find the best and worst
abest:=min(Step2);
aworst:=max(Step2);

## number of best and worst criteria
nn1:=0;nn2:=0;
for i1 from 1 to n do
if Step2[i1]=Step2[1] then nn1:=nn1+1; bob[nn1]:=i1; else i1:=n; end if;
end do;
for i2 from 1 to n do
if Step2[n+1-i2]=Step2[n] then nn2:=nn2+1; bow[nn2]:=n+1-i2; else i2:=n; end if;
end do;

# if all has 1, i.e if all criteria are equal
if nn1=n1 then print("all criteria are equal and have same weights=",evalf(1/n1)); end if;


if nn1=1 then print("the best criterion",Step1[bob[nn1]]);
else if nn1<>n1 then print("the best criteria",seq(Step1[bob[j]],j=1..nn1)); end if;
end if;
if nn2=1 then print("the worst criterion",Step1[bow[nn2]]);
else if nn1<>n1 then print("the worst criteria",seq(Step1[bow[j]],j=1..nn2)); end if;
end if;

## FUCOM for Step2-a computation

sumw:=0;
sumw1:=0;
nn5:=0;nn6:=0;nn7:=0;nn8:=0;
for i from 1 to n-1 do

nn5:=nn5+2;
sumBOL[nn5-1]:=(w3[Step1[i]]/w3[Step1[i+1]]-Step2[i+1])<=x;
sumBOL[nn5]:=(w3[Step1[i]]/w3[Step1[i+1]]-Step2[i+1])>=-x;

end do;
for i from 1 to n-2 do

nn6:=nn6+2;
sumOWL[nn6-1]:=(w3[Step1[i]]/w3[Step1[i+2]]-(Step2[i+1])*(Step2[i+2]))<=x;
sumOWL[nn6]:=(w3[Step1[i]]/w3[Step1[i+2]]-(Step2[i+1])*(Step2[i+2]))>=-x;

end do;

try
sol1:=Minimize(x,{seq(sumBOL[j],j=1..nn5),seq(sumOWL[j],j=1..nn6),add(w3[Step1[j]],j=1..n)=1},assume=nonnegative)
catch "no improved point could be found":
sol1:=Minimize(x,{seq(sumBOL[j],j=1..nn5),seq(sumOWL[j],j=1..nn6),add(w3[Step1[j]],j=1..n)=1},assume=nonnegative,feasibilitytolerance=10^(-10))
end try;
assign(sol1[2]);


print("the FUCOM results are as follows:");
seq(printf("\t\r weight of %a=%a",Step1[i],w3[Step1[i]]),i=1..n);
printf("\t\r DFC=%a",sol1[1]);
end if;


## Step2-b part
if ComparisonStyle=2 then
print("You are using the comparison vector in Step2-b");

## find the best and worst
abest:=min(Step2);
aworst:=max(Step2);

if abest<>1 then error "only best-best comparison (only the first element of Step2) should be 1"; end if;

# check ranking
for i from 1 to n-1 do
if Step2[i]>Step2[i+1] then 
printf("\t\r The solution might be wrong! Please construct your Step2 for the comparison with respect to the best (first) criterion, see Step2-(b), and revise the following ranking: %a",Step1[i+1]>Step1[i]); end if;
end do;

print("the number of the criteria",n1);

## number of best and worst criteria
nn1:=0;nn2:=0;
for i from 1 to n do
if Step2[i]=abest then nn1:=nn1+1; bob[nn1]:=i; end if;
if Step2[i]=aworst then nn2:=nn2+1; bow[nn2]:=i; end if;
end do;

# if all has 1, i.e if all criteria are equal
if nn1=n1 then print("all criteria are equal and have same weights=",evalf(1/n1)); end if;



if nn1=1 then print("the best criterion",Step1[bob[nn1]]);
else if nn1<>n1 then print("the best criteria",seq(Step1[bob[j]],j=1..nn1)); end if;
end if;
if nn2=1 then print("the worst criterion",Step1[bow[nn2]]);
else if nn1<>n1 then print("the worst criteria",seq(Step1[bow[j]],j=1..nn2)); end if;
end if;
if nn1<>n1 then print("the value of the best-worst comparison",aworst); end if;

## FUCOM for Step2-b computation

sumw:=0;
sumw1:=0;
nn5:=0;nn6:=0;nn7:=0;nn8:=0;
for i from 1 to n-1 do

nn5:=nn5+2;
sumBOL[nn5-1]:=(w3[Step1[i]]/w3[Step1[i+1]]-Step2[i+1]/Step2[i])<=x;
sumBOL[nn5]:=(w3[Step1[i]]/w3[Step1[i+1]]-Step2[i+1]/Step2[i])>=-x;

end do;
for i from 1 to n-2 do

nn6:=nn6+2;
sumOWL[nn6-1]:=(w3[Step1[i]]/w3[Step1[i+2]]-(Step2[i+1]/Step2[i])*(Step2[i+2]/Step2[i+1]))<=x;
sumOWL[nn6]:=(w3[Step1[i]]/w3[Step1[i+2]]-(Step2[i+1]/Step2[i])*(Step2[i+2]/Step2[i+1]))>=-x;

end do;

try
sol1:=Minimize(x,{seq(sumBOL[j],j=1..nn5),seq(sumOWL[j],j=1..nn6),add(w3[Step1[j]],j=1..n)=1},assume=nonnegative)
catch "no improved point could be found":
sol1:=Minimize(x,{seq(sumBOL[j],j=1..nn5),seq(sumOWL[j],j=1..nn6),add(w3[Step1[j]],j=1..n)=1},assume=nonnegative,feasibilitytolerance=10^(-10))
end try;
assign(sol1[2]);


print("the FUCOM results are as follows:");
seq(printf("\t\r weight of %a=%a",Step1[i],w3[Step1[i]]),i=1..n);
printf("\t\r DFC=%a",sol1[1]);

end if;

end proc:
