private void getWeights(Collection<Double> inputs, GravityCenter weights, double[] ranges) {
   int left = 0, right = 0;
   double avgValue = weights.avgValue;
   for (double i : inputs) {
     if (i < ranges[0] || i > ranges[1]) continue;
     if (i >= avgValue) right++;
     else left++;
   }
   weights.leftWeight = left;
   weights.rightWeight = right;
 }
 private void getAverage(Collection<Double> inputs, GravityCenter wts, double[] ranges) {
   double min = Long.MAX_VALUE;
   double max = Long.MIN_VALUE;
   for (double i : inputs) {
     if (i < ranges[0] || i > ranges[1]) continue;
     if (i < min) min = i;
     else if (i > max) max = i;
   }
   wts.minValue = min;
   wts.maxValue = max;
   wts.avgValue = (max / 2 - min / 2);
 }
  private GravityCenter distribute(Collection<Double> inputs, double[] ranges) {
    GravityCenter wts = new GravityCenter();

    getAverage(inputs, wts, ranges);
    int loops = 0;
    while (true) {
      loops++;
      if (loops > 30) break;

      /**
       * System.out.println("Min:" + wts.minValue + " Avg:" + wts.avgValue + " Max:" + wts.maxValue
       * + " LeftW:" + wts.leftWeight + " RightW:" + wts.rightWeight);
       */
      getWeights(inputs, wts, ranges);

      if (wts.leftWeight > wts.rightWeight) {
        double avgValue = wts.avgValue;
        wts.avgValue = avgValue - (avgValue / 2 - wts.minValue / 2);
        wts.maxValue = avgValue;
      } else {
        double avgValue = wts.avgValue;
        wts.avgValue = avgValue + (wts.maxValue / 2 - avgValue / 2);
        wts.minValue = avgValue;
      }

      int diff =
          (wts.leftWeight > wts.rightWeight)
              ? (wts.leftWeight - wts.rightWeight)
              : (wts.rightWeight - wts.leftWeight);
      if (diff <= 1) {
        /**
         * System.out.println("Min:" + wts.minValue + " Avg:" + wts.avgValue + " Max:" +
         * wts.maxValue + " LeftW:" + wts.leftWeight + " RightW:" + wts.rightWeight);
         */
        break;
      }
    }
    return wts;
  }