% this function finds the closes k neighbors to a row within a dataset
% and returns the median of those k projects' effort values
% and also the mre value


function [knnMedian, mre, kEffort] = nnk(myRow,train,kValue)
featureSize = size(train,2);

if(size(train,1) < kValue)
    kValue = size(train,1);
end

% normalize dataset to 0-1 interval
train = [myRow;train];    % combine test and train
train = myNormalizer(train); % normalize combination
myRow = train(1,:);   % separate test from normalized data
train(1,:) = [];  % delete test from train

% below array keeps the kNN effort values
kEffort = zeros(kValue,1);

for counter = 1:kValue
    
   % initially let the first instance have the best distance
   bestDist = sqrt(abs(myRow(1,1:(featureSize-1)).^2 - train(1,1:(featureSize-1)).^2)); 
   bestIndex = 1; 
   
   for i=2:size(train,1)
       tempDist = sqrt(abs(myRow(1,1:1:(featureSize-1)).^2 - train(i,1:(featureSize-1)).^2));
       if tempDist < bestDist
          bestDist = tempDist;
          bestIndex = i;
       end
   end
   
   % save the effort value of the closest neighbor
   kEffort(counter,1) = train(bestIndex,featureSize);
   
   % delete the closest neighbor for the next run (if there is any)
   train(bestIndex,:) = [];
   
end

% return the median of the kNN
knnMedian = median(kEffort);

mre = abs(knnMedian - myRow(1,featureSize))/myRow(1,featureSize);

end