function [ x, cost, avgRT, cdfRTindex, cdfRTvalue, evaluations, time ] = findOptimalAllocationFullNFmincon(qn, constraints, resources, x0)
% FINDOPTIMALALLOCATIONNFULL
% Calculate an optimal allocation for the stations of a queuing network on a set
% of resources, subject to some constraints on the response time
% INPUT
% qn: input queuing network
% constraints: response time constraints
% resources: types of available resources
% numResources: number of resources to allocate
% OUTPUT
% x: allocation matrix
% cost: cost fo allocating the allocation matrix
% avgRT: mean response time
% cdfRTindex: response time percentiles indexes
% cdfRTvalue: response time percentiles values
% evaluations: number of evaluations
% time: time to computer the solution.

	time = cputime;

	% initializations
	opt = FullProblem(qn, constraints, resources);
	objfun = @opt.objfun;
	nnlcon = @opt.nnlcon;
	
	disp(['Solving the problem using ' num2str(size(x0,2)) ' resources and the following initial point x0:']);
	disp(x0);

	%% options
	MaxCheckIter=1000;
	options = optimset();
	options.Display = 'iter';
	options.LargeScale = 'off';
	options.MaxIter =  100;
	options.MaxFunEvals = 100;
	options.MaxSQPIter = 500;
	options.TolCon = 1e-8;
	options.Algorithm = 'interior-point';
	options.OutputFcn =  @outfun;

	XLB = x0.*0; % lower bounds on x variables
	XUB = []; % x0;
	x0 = x0 - options.TolCon;

	T0 = tic; % needed for outfun

	%% optimization program
	[x]=fmincon(objfun,x0,[],[],[],[],XLB,XUB,nnlcon,options);

	allocatedQN = opt.calculateAllocatedQN(x);
	[avgRT, cdfRTindex, cdfRTvalue] = evaluateRT(allocatedQN);
	evaluations = opt.evaluations + 1;
%	[needed, allocation] = opt.calculateNeededAllocation(x0);

	time = cputime - time;
	
	% calculate the cost
	[u, v] = size(x);
	
	cost = 0;
	for ii=1:v
		cost = cost + ...
			resources.cost(resources.bestFitResourceIndex(sum(x(:,v))));
	end
	
	function stop = outfun(x, optimValues, state)
	  global MAXTIME;
	  %disp('Trying x=');
	  %disp(num2str(x));
	  stop = false;
	  if strcmpi(state,'iter')
			if mod(optimValues.iteration,MaxCheckIter)==0 && optimValues.iteration>1
				 reply = input('Do you want more? Y/N [Y]: ', 's');
				 if isempty(reply)
					  reply = 'Y';
				 end
				 if strcmpi(reply,'N')
					  stop=true;
				 end
			end
			if toc(T0)>MAXTIME
				 fprintf('Time limit reached. Aborting.\n');
				 stop = true;
			end
	  end
	end

end
