@Override
	public double getHeuristicValue(Object state) {
		GardenPlan garden = (GardenPlan) state;
		if (!garden.isValid()) {
			throw new IllegalStateException("Illeagl garden state generated after sometime");
			//return Long.MAX_VALUE;
		}
		double value = 0;
		int numVarietyInGarden = 0;
		for (IGMVVariety var : garden.getVarieties()) {
			if (var.getActualRowLength() > 0) {
				numVarietyInGarden++;
			}
		}

		value -= W1 * numVarietyInGarden;
		double highestDev = 0;
		for (IGMVVegetable veg : garden.getVegetables()) {
			value -= (W2 * veg.getActualVegetableQuantity() * veg
					.getDesirabilityIndex());
			
			value += W4 * veg.getDeviationInShare();
			if (highestDev < veg.getDeviationInShare()) {
				highestDev = veg.getDeviationInShare();
			}
			//value += W4 * veg.getPercentageDeviationInShare();
			boolean nullifyDevPunishemnet = false;
			for (IGMVVariety v : veg.getVarieties()) {
				
				if (v.getActualRowLength() > 0
						&& (v.getRequiredExp() > garden.getUserExp())) {
					value += W3
							* (v.getRequiredExp() - garden.getUserExp()) * v.getVarietyShare() ;
					if(!nullifyDevPunishemnet) {
						value -= W4 * veg.getDeviationInShare();
					}
					nullifyDevPunishemnet = true;
				}
//				else {
//					value -= W4 * (veg.getDesiredShare() - v.getVarietyShare());
//				}
			}
		}

		value += W5 * highestDev;
		return value;
	}