function [relValues, lambda, policy, count] = FindPolicyRelVI(contribArray, ...
    transArray, feasibleActions, optDir, myeps, maxIter)
% The last state is the reference state
numStates = length(feasibleActions);
oldRelValues = zeros(numStates,1);
newRelValues = zeros(numStates,1);
newValues = zeros(numStates,1);
stopit = false;
count = 1;
while (~stopit)
    count = count + 1;
    % iterate values
    if strcmpi(optDir, 'min')
        for j = 1:numStates
            newValues(j) = findMin(j,oldRelValues);
        end
    else
        for j = 1:numStates
            newValues(j) = findMax(j,oldRelValues);
        end
    end
    lambda = newValues(numStates);
    newRelValues = newValues - lambda;
    delta = newRelValues - oldRelValues;
    if (max(delta) - min(delta) < myeps) || (count > maxIter)
        stopit = true;
    else
        count = count + 1;
        oldRelValues = newRelValues;
    end
end
relValues = newRelValues;
% get Policy
policy = zeros(numStates,1);
if strcmpi(optDir, 'min')
    for j = 1:numStates
        [~, policy(j)] = findMin(j, relValues);
    end
else
    for j = 1:numStates
        [~, policy(j)] = findMax(j, relValues);
    end
end

% nested functions
% find min cost action and state value
    function [valBest, best] = findMin(k,vals)
        best = NaN;
        valBest = inf;
        act = feasibleActions{k};
        for a = 1:length(act)
            aux = contribArray(k,act(a)) + dot(transArray(k,:,act(a)), vals);
            if aux < valBest
                valBest = aux;
                best = act(a);
            end
        end
    end
% find max reward action and state value
    function [valBest, best] = findMax(k,vals)
        best = NaN;
        valBest = -inf;
        act = feasibleActions{k};
        for a = 1:length(act)
            aux = contribArray(k,act(a)) + dot(transArray(k,:,act(a)), vals);
            if aux > valBest
                valBest = aux;
                best = act(a);
            end
        end
    end

end


