/**
   * Método que verifica se a regra passa como parâmetro é igual nos atributo discreto e se todos
   * atributos numericos contem um intervalo que se cruzem
   *
   * @param r2 Regra a ser compararada com a atual
   * @return true se as regras se cruzam, false se são diferentes
   */
  public boolean verificarIntervalos(Regra r2) {
    if (this.cabeca != r2.cabeca) return false;
    for (int i = 0; i < corpo.length; i++) {
      Atributo at1 = this.corpo[i];
      Atributo at2 = r2.corpo[i];
      // Se o atributo das duas regras forem vazio o atributo tem o valor igual
      // Se uma é vazio e a outra não as regras são diferentes
      // Se as duas não são vazias, deve ser comparado o valor dos atributos.
      if (at1.isVazio()) {
        if (!at2.isVazio()) return false;
      } else {
        if (at2.isVazio()) return false;
        else {
          if (at1.isNominal()) {
            double[] v1 = at1.getValores();
            double[] v2 = at2.getValores();
            if ((v1[0] != v2[0]) || (v1[1] != v2[1])) return false;
          } else {
            double[] v1 = at1.getValores();
            double[] v2 = at2.getValores();

            if ((v1[1] < v2[0]) || v2[1] < v1[0]) return false;
          }
        }
      }
    }

    return true;
  }
 /**
  * Método que preencher uma regra atraves de um array de valores obtido pela nuvem de particulas
  *
  * @param novosValores Array com os novos valores para a a regra
  */
 public void preencherRegraArray(double[] novosValores) {
   int j = 0;
   for (int i = 0; i < corpo.length; i++) {
     Atributo atributo = corpo[i];
     if (atributo.isNominal()) {
       // Diminui o valor de 1 para voltar aos valores normais no padrao do weka (vazio == -1).
       double valor = novosValores[j++] - 1;
       atributo.atualizar(valor, AtributoNominal.igual);
     } else {
       AtributoNumerico a = (AtributoNumerico) atributo;
       double valor1 = novosValores[j++];
       double valor2 = novosValores[j++];
       if ((valor1 == valor2) && (valor1 == a.limiteMinimo || valor1 == a.limiteMaximo))
         atributo.atualizar(Double.MIN_VALUE, Double.MIN_VALUE);
       else atributo.atualizar(valor1, valor2);
     }
   }
   getNumAtributosNaoVazios();
 }
  /**
   * Método que retorna os valores dos atributos no formato de array. Utilizado no metodo de nuvem
   * de partículas
   *
   * @return Todos os valores dos atributos no formato array
   */
  public double[] obterCorpoArray() {
    ArrayList<Double> valoresAtributos = new ArrayList<Double>();
    for (int i = 0; i < corpo.length; i++) {
      Atributo atributo = corpo[i];
      double[] valores = atributo.getValores();
      if (atributo.isNominal()) {
        // Caso o atributo seja nominal só é adicionado o valor do atributo.
        if (atributo.isVazio()) valoresAtributos.add(new Double(0));
        else {
          // Adicao de 1 no valor do atributo para representar o valor vazio como sendo 0;
          double temp = valores[0] + 1;
          valoresAtributos.add(new Double(temp));
        }
      } else {
        // Caso seja numerico, os dois valores do limite sao adicionados.
        AtributoNumerico a = (AtributoNumerico) atributo;
        if (atributo.isVazio()) {
          valoresAtributos.add(new Double(a.limiteMinimo));
          valoresAtributos.add(new Double(a.limiteMinimo));
        } else {
          valoresAtributos.add(new Double(valores[0]));
          valoresAtributos.add(new Double(valores[1]));
        }
      }
    }

    // Gerar regras somente de uma classe
    // valoresAtributos.add(new Double(cabeca+1));

    double[] retorno = new double[valoresAtributos.size()];

    int i = 0;
    for (Iterator<Double> iter = valoresAtributos.iterator(); iter.hasNext(); ) {
      Double valor = (Double) iter.next();
      retorno[i++] = valor.doubleValue();
    }
    return retorno;
  }