@Override
	//Quick and dirty implementation, needs some hard revision
	public AbstractStochasticLotSizingSolution solve(
			AbstractStochasticLotSizingProblem problem, boolean[] setupPattern)
			throws SolvingInitialisiationException,
			ConvolutionNotDefinedException {
		
		//Check inputs
		if (problem.getPeriods().length != setupPattern.length) throw new SolvingInitialisiationException("Problem and setup pattern have different planning horizons.");
		
		//Get the vector of aggregated demand (there is no ADI in this approach)
		RealDistribution openOrders = null;
		NegatableDistribution realizedOrders = null;
		NegatableDistribution[] realizedOrderArray = null;		
		
		int setupPeriod = -1;
		double inventoryCost = 0.0;
		double setupCost = 0.0;
		double[] orderUpToLevelForOpenDemand = new double[setupPattern.length];
		
		for (int t = 0; t < setupPattern.length;t++){
			if (setupPattern[t]){
				setupPeriod = t;
				setupCost += problem.getPeriods()[t].getSetupCost();
				int nextSetupPeriod = t+1;
				
				while(nextSetupPeriod < setupPattern.length && !setupPattern[nextSetupPeriod]){
					nextSetupPeriod++;
				}
				
				openOrders = problem.getPeriods()[t].openDemand(t, setupPeriod);
				realizedOrderArray = new NegatableDistribution[nextSetupPeriod-setupPeriod];
				realizedOrderArray[0] = (NegatableDistribution) problem.getPeriods()[t].realisedDemand(t, setupPeriod);
				for (int tau = t+1; tau < nextSetupPeriod; tau++){
					 openOrders = Convoluter.convolute(openOrders, problem.getPeriods()[tau].openDemand(tau, setupPeriod));
					 realizedOrderArray[tau-t] = (NegatableDistribution) problem.getPeriods()[tau].realisedDemand(tau, setupPeriod);
				}
				
				orderUpToLevelForOpenDemand[t] = openOrders.inverseCumulativeProbability(problem.getServiceLevel());
				
				
				openOrders = problem.getPeriods()[t].openDemand(t, setupPeriod);
				realizedOrders = (NegatableDistribution) Convoluter.convolute(realizedOrderArray, 1, realizedOrderArray.length);
				RealDistribution effectiveDemandDistribution = Convoluter.convolute(openOrders, realizedOrders.negate());
				StockFunction stockFunction = new StockFunction(effectiveDemandDistribution);
				inventoryCost += problem.getPeriods()[t].getInventoryHoldingCost()*stockFunction.value(orderUpToLevelForOpenDemand[setupPeriod]);
			}
			else{
				openOrders = Convoluter.convolute(openOrders,problem.getPeriods()[t].openDemand(t, setupPeriod));
				realizedOrders = (NegatableDistribution) (NegatableDistribution) Convoluter.convolute(realizedOrderArray, t-setupPeriod+1, realizedOrderArray.length);
				RealDistribution effectiveDemandDistribution = Convoluter.convolute(openOrders, realizedOrders.negate());
				StockFunction stockFunction = new StockFunction(effectiveDemandDistribution);
				inventoryCost += problem.getPeriods()[t].getInventoryHoldingCost()*stockFunction.value(orderUpToLevelForOpenDemand[setupPeriod]);
			}
		}
		
		return new SimpleStochasticLotSizingSolution(setupCost, inventoryCost, "Order-up-to-level for open demand", orderUpToLevelForOpenDemand, setupPattern);
		
	}