/**
   * Returns a representation of of the population in the form of a table, where each row represents
   * one individual, one parameter per column, and the last column containing the objective value.
   *
   * @returns a table represeting the population.
   */
  public Table getTable() {

    Table vt;

    int rowCount = solutions.length;
    int colCount = ranges.length + 1;

    Column[] cols = new Column[colCount];

    // make a column for each range
    for (int i = 0; i < ranges.length; i++) {
      Column c;

      if (ranges[i] instanceof DoubleRange) {
        c = new DoubleColumn(rowCount);
        for (int j = 0; j < rowCount; j++) {
          double d = solutions[j].getDoubleParameter(i);
          ((DoubleColumn) c).setDouble(d, j);
        }
      } else if (ranges[i] instanceof IntRange) {
        c = new IntColumn(rowCount);
        for (int j = 0; j < rowCount; j++) {
          int in = (int) solutions[j].getDoubleParameter(i);
          ((IntColumn) c).setInt(in, j);
        }
      } else if (ranges[i] instanceof BinaryRange) {
        c = new BooleanColumn(rowCount);
        for (int j = 0; j < rowCount; j++) {
          boolean b = (solutions[j].getDoubleParameter(i) > 0);
          ((BooleanColumn) c).setBoolean(b, j);
        }
      } else { // i guess default to a double column
        c = new DoubleColumn(rowCount);
        for (int j = 0; j < rowCount; j++) {
          double d = solutions[j].getDoubleParameter(i);
          ((DoubleColumn) c).setDouble(d, j);
        }
      }

      c.setLabel(ranges[i].getName());
      cols[i] = c;
    }
    // now the objective
    DoubleColumn objC = new DoubleColumn(rowCount);
    objC.setLabel(objConstraints.getName());
    for (int j = 0; j < rowCount; j++) {
      objC.setDouble(solutions[j].getObjective(), j);
    }
    cols[colCount - 1] = objC;

    vt = new MutableTableImpl(cols);
    return vt;
  }
  /* returns a string with info on the ranges, obj constraints, etc
   */
  public String getSpaceDefinitionString() {
    StringBuffer sb = new StringBuffer();

    sb.append("\nRanges:\n");
    sb.append("\t_Name_\t_Min_\t_Max_\n");
    for (int i = 0; i < ranges.length; i++) {
      sb.append("\t");
      sb.append(ranges[i].getName());
      sb.append("\t");
      sb.append(ranges[i].getMin());
      sb.append("\t");
      sb.append(ranges[i].getMax());
      sb.append("\n");
    }
    sb.append("\nObjective Constraint:\n");
    sb.append("\t_Name_\t_Is Maximizing?_\n");
    sb.append("\t");
    sb.append(objConstraints.getName());
    sb.append("\t");
    sb.append(objConstraints.isMaximizing());
    sb.append("\n");
    return (sb.toString());
  }
 /**
  * Compare one member to another. This requires knowledge of the fitness function which cannot be
  * supplied here, hence must be provided in a subclass.
  *
  * @returns 1 if member indexed a is greater than b, 0 if they are equal, -1 if member indexed by
  *     a is less than b.
  */
 public int compareSolutions(Solution a, Solution b) {
   double af = ((SOSolution) a).getObjective();
   double bf = ((SOSolution) b).getObjective();
   return objConstraints.compare(af, bf);
 }