function [Prob, Soln] = Solver(Prob, SaveType, Soln);

%
% Make sure the image directory exists
%
if ~isdir('../images/AngleAssignments')
   !mkdir ../images/AngleAssignments
end

%
% Get Informed PDFs for several solvers
%
% PDF-Types
%    0 - barrier
%    1 - primal simplex
%    2 - dual simplex
%    3 - Weakly Informed Set Cover - scaled by dose rates
%    4 - Weakly Informed Set Cover - unscaled by dose rates
%    5 - Weak Scoring
%
for j = 0:5

%
% We calculate the Balanced PDF from the barrier (interior point) sol'n
%
if j == 0
   Prob.SolverType = j;
   % Get System clock
   t0 = clock;
   Prob = Solver(Prob, 'cplex');
   % Catalog system times (do not include angle aggregation
   Soln.AngleAssignment.InteriorAvg.Time = etime(clock, t0)/60;
   Soln.AngleAssignment.InteriorMax.Time = ...
      Soln.AngleAssignment.InteriorAvg.Time;
   t0 = clock;
   Prob.BalancedSoln = BalancedPDF(Prob);
   Soln.AngleAssignment.BalancedAvg.Time = etime(clock, t0)/60 + ...
      Soln.AngleAssignment.InteriorAvg.Time;
   Soln.AngleAssignment.BalancedMax.Time = etime(clock, t0)/60 + ...
      Soln.AngleAssignment.InteriorAvg.Time;
   Soln.AngleAssignment.JudgementValue = Prob.fval;
   LogMesg(sprintf('RAD -> Successfully solved for SolverType %d', j));
   Prob.InteriorAvg = zeros(1,Prob.NumAngles);
   Prob.BalancedAvg = zeros(1,Prob.NumAngles);
   Prob.InteriorMax = zeros(1,Prob.NumAngles);
   Prob.BalancedMax = zeros(1,Prob.NumAngles);
   Prob.EntropyAvgBalanced = zeros(1, Prob.NumAngles);
   ColInd = 1;
   for a = 1:Prob.NumAngles
      Prob.InteriorAvg(a) = ...
         sum(Prob.ThePlan( ColInd : ColInd + Prob.NumPencils(a) - 1 ));
      Prob.BalancedAvg(a) = ...
         sum(Prob.BalancedSoln( ColInd : ColInd + Prob.NumPencils(a) - 1 ));
      Prob.InteriorMax(a) = ...
         max(Prob.ThePlan( ColInd : ColInd + Prob.NumPencils(a) - 1 ));
      Prob.BalancedMax(a) = ...
         max(Prob.BalancedSoln( ColInd : ColInd + Prob.NumPencils(a) - 1 ));
      ColInd = ColInd + Prob.NumPencils(a);
   end
   ColInd = 1;
   t0 = clock;
   for a = 1:Prob.NumAngles
      % Calculate angles Entropy
      Prob.EntropyAvgBalanced(a) = sum(...
         Prob.BalancedSoln(ColInd : ColInd + Prob.NumPencils(a) -1) .* ...
         log(max(Prob.BalancedSoln(ColInd : ColInd + Prob.NumPencils(a) -1), ...
         10^(-10)*ones(Prob.NumPencils(a), 1)) ) );
      ColInd = ColInd + Prob.NumPencils(a);
   end
   % Calculate Entropy PDFs
   if max(Prob.EntropyAvgBalanced) > 0
      Prob.EntropyAvgBalanced = (1/max(Prob.EntropyAvgBalanced)) * ...
         (Prob.EntropyAvgBalanced - min(Prob.EntropyAvgBalanced));
   else
      Prob.EntropyAvgBalanced = zeros(size(Prob.EntropyAvgBalanced)); 
   end
   % Record System time
   Soln.AngleAssignment.EntropyAvgBalanced.Time = etime(clock, t0)/60 + ...
      Soln.AngleAssignment.BalancedAvg.Time;
   %
   % Plot and save these PDfs
   %
   figure
   plot(1:Prob.NumAngles, Prob.InteriorAvg);
   saveas(gcf,['../images/AngleAssignments/InteriorAvg'], SaveType)
   figure
   plot(1:Prob.NumAngles, Prob.InteriorMax);
   saveas(gcf,['../images/AngleAssignments/InteriorMax'], SaveType)
   figure
   plot(1:Prob.NumAngles, Prob.BalancedAvg);
   saveas(gcf,['../images/AngleAssignments/BalancedAvg'], SaveType)
   figure
   plot(1:Prob.NumAngles, Prob.BalancedMax);
   saveas(gcf,['../images/AngleAssignments/BalancedMax'], SaveType)
   figure
   plot(1:Prob.NumAngles, Prob.EntropyAvgBalanced);
   saveas(gcf,['../images/AngleAssignments/EntropyAvgBalanced'], SaveType)

%
% Find the PDFs for the primal simplex
%
elseif j == 1
   Prob.SolverType = j;
   t0 = clock;
   Prob = Solver(Prob, 'cplex');
   Soln.AngleAssignment.PrimalAvg.Time = etime(clock, t0)/60;
   Soln.AngleAssignment.PrimalMax.Time = etime(clock, t0)/60;
   LogMesg(sprintf('RAD -> Successfully solved for SolverType %d', j));
   Prob.PrimalAvg = zeros(1,Prob.NumAngles);
   Prob.PrimalMax = zeros(1,Prob.NumAngles);
   ColInd = 1;
   for a = 1:Prob.NumAngles
      Prob.PrimalAvg(a) = ...
         sum(Prob.ThePlan( ColInd : ColInd + Prob.NumPencils(a) - 1));
      Prob.PrimalMax(a) = ...
         max(Prob.ThePlan( ColInd : ColInd + Prob.NumPencils(a) - 1));
      ColInd = ColInd + Prob.NumPencils(a);
   end
   figure
   plot(1:Prob.NumAngles, Prob.PrimalAvg);
   saveas(gcf,['../images/AngleAssignments/PrimalAvg'], SaveType)
   figure
   plot(1:Prob.NumAngles, Prob.PrimalMax);
   saveas(gcf,['../images/AngleAssignments/PrimalMax'], SaveType)
%
% Find the PDFs for the Dual simplex
%
elseif j == 2
   Prob.SolverType = j;
   t0 = clock;
   Prob = Solver(Prob, 'cplex');
   Soln.AngleAssignment.DualAvg.Time = etime(clock, t0)/60;
   Soln.AngleAssignment.DualMax.Time = etime(clock, t0)/60;
   LogMesg(sprintf('RAD -> Successfully solved for SolverType %d', j));
   Prob.DualAvg = zeros(1,Prob.NumAngles);
   Prob.DualMax = zeros(1,Prob.NumAngles);
   ColInd = 1;
   for a = 1:Prob.NumAngles
      Prob.DualAvg(a) = ...
         sum(Prob.ThePlan( ColInd : ColInd + Prob.NumPencils(a) - 1 ));
      Prob.DualMax(a) = ...
         max(Prob.ThePlan( ColInd : ColInd + Prob.NumPencils(a) - 1 ));
      ColInd = ColInd + Prob.NumPencils(a);
   end
   figure
   plot(1:Prob.NumAngles, Prob.DualAvg);
   saveas(gcf,['../images/AngleAssignments/DualAvg'], SaveType)
   figure
   plot(1:Prob.NumAngles, Prob.DualMax);
   saveas(gcf,['../images/AngleAssignments/DualMax'], SaveType)
%
% Find the PDF for the Scaled weakly informed set cover technique.
%
elseif j == 3
   t0 = clock;
   Prob.SetCover1 = SetCovPDF(Prob,'ScaledWeak',[]);
   Soln.AngleAssignment.SetCover1.Time = etime(clock, t0)/60;
   figure
   plot(1:Prob.NumAngles, Prob.SetCover1);
   saveas(gcf,['../images/AngleAssignments/ScaledWeakSetCover'], SaveType)
   LogMesg('RAD -> Successfully Calculated Scaled Weak SetCover PDF')
%
% Find the PDF for the Unscaled weakly informed set cover technique.
%
elseif j == 4
   t0 = clock;
   Prob.SetCover2 = SetCovPDF(Prob, 'UnScaledWeak', []);
   Soln.AngleAssignment.SetCover2.Time = etime(clock, t0)/60;
   figure
   plot(1:Prob.NumAngles, Prob.SetCover2);
   saveas(gcf,['../images/AngleAssignments/UnscaledWeakSetCover'], SaveType)
   LogMesg('RAD -> Successfully Calculated Unscaled Weak SetCover PDF')
%
% Find the PDFs for the scoring technique
%
elseif j == 5
   t0 = clock;
   Prob.Scoring = SetCovPDF(Prob, 'Scoring', []);
   Soln.AngleAssignment.Scoring.Time = etime(clock, t0)/60;
   figure
   plot(1:Prob.NumAngles, Prob.Scoring);
   saveas(gcf,['../images/AngleAssignments/Scoring'], SaveType)
   LogMesg('RAD -> Successfully Calculated Scoring PDF')
else
   LogMesg('RAD -> WARNING in PDFmaker: Unknown Solver Type')
end

%
% End for loop for different solvers
%   
end
