示例#1
0
double handle_op_sum(stack_t **args, int *is_bad_formula)
{
    if (*args == NULL)
        goto error;

    double result = 0.0, operand;
    char *front = pop_copy(args);
    while(front != NULL) {
        operand = atof(front, cgc_strlen(front) + 1, is_bad_formula);
        free(front);
        if(*is_bad_formula)
            goto error;

        result += operand;
        front = pop_copy(args);
    }

    goto done;

error:
    *is_bad_formula = 1;
	result = 0.0;
done:
    return result;
}
示例#2
0
double handle_op_count(stack_t **args, int *is_bad_formula)
{
    size_t i = 0;
    if (*args == NULL)
        goto error;

    double result = 0.0, operand;
    char *front = pop_copy(args);
    while(front != NULL) {
        operand = atof(front, cgc_strlen(front) + 1, is_bad_formula);
        free(front);
        if(*is_bad_formula)
            goto error;

        front = pop_copy(args);
        i++;
    }

    result = i;
    goto done;

error:
    clear_stack(args);
    *is_bad_formula = 1;
	result = 0.0;
done:
    if (i == 0) {
        i = 1;
        goto error;
    }
    return result;
}
示例#3
0
static int eval_function(operator_t *op, stack_t **values, char *val_str, size_t size)
{
    if (op == NULL || val_str == NULL || size <= 2)
        return -1;

    double val = 0.0;
    char *arg;
    char *op_name = (char *) op->name;
    size_t i, num_args = 0;
    int is_bad_formula = 0;
    operator_t *nested_op;

    stack_t *args = NULL;
    if (is_arg_arithmetic(op_name)) {
        num_args = 2;
    } else {
        char *arg_count = pop_copy(values);
        if (arg_count == NULL)
            goto error;

        num_args = strtol(arg_count, NULL, 10);
        free(arg_count);
    }

    for (i = 0; i < num_args; i++) {
        arg = pop_copy(values);
        //printf("arg[%d]==%s\n", i, arg);
        if (parsearg(arg) == FUNCTION) {
            nested_op = get_op(arg);
            free(arg);
            if (eval_function(nested_op, values, val_str, size) == 0)
                push_copy(&args, val_str, size);
            else
                goto error;

        } else if (push(&args, arg) != 0) {
            goto error;
        }
    }

    val = op->function(&args, &is_bad_formula);
    if (is_bad_formula)
        goto error;

    if (ftoa(val, val_str, size) == NULL)
        goto error;

    return 0;

error:
    clear_stack(&args);
    return -1;
}
示例#4
0
double handle_op_power(stack_t **args, int *is_bad_formula)
{
    if (*args == NULL)
        goto error;

    double result = 0.0, operand1, operand2;
    char *front;

    // Get first operand
    front = pop_copy(args);
    if (front == NULL)
        goto error;
    operand1 = atof(front, cgc_strlen(front) + 1, is_bad_formula);
    free(front);
    if(*is_bad_formula)
        goto error;

    // Get second operand
    front = pop_copy(args);
    if (front == NULL)
        goto error;
    operand2 = atof(front, cgc_strlen(front) + 1, is_bad_formula);
    free(front);
    if(*is_bad_formula)
        goto error;

    if (*args != NULL)
        goto error;     // Too many arguments

    if (operand2 == 0.0)
        result = 1.0;
    else if (operand2 == 1.0)
        result = operand1;
    else if (isnan(operand2))
        result = operand2;
    else if (operand1 == 0 && operand2 > 0)
        result = 0.0;
    else if (operand1 < 0 && remainder(operand2, 1) == 0.0)
        result = pow(-operand1, operand2) * (remainder(operand2, 2) == 0 ? 1 : -1);
    else
        result = pow(operand1, operand2);
    goto done;

error:
    clear_stack(args);
    *is_bad_formula = 1;
	result = 0.0;
done:
    return result;
}
示例#5
0
double handle_op_stddev(stack_t **args, int *is_bad_formula)
{
    size_t i = 0;
    if (*args == NULL)
        goto error;

    double result = 0.0, operand, mean = 0.0;
    stack_t *tmp = *args;

    while (tmp != NULL) {
        operand = atof(tmp->data, cgc_strlen(tmp->data) + 1, is_bad_formula);
        if(*is_bad_formula)
            goto error;

        mean += operand;
        i++;
        tmp = tmp->next;
    }
    if (i == 0)
        goto done;
    mean /= i;

    i = 0;
    char *front = pop_copy(args);
    while(front != NULL) {
        operand = atof(front, cgc_strlen(front) + 1, is_bad_formula);
        free(front);

        //TODO - Look into this, I don't know why pow is failing
        //result += (pow((operand - mean), 2.0));
        result += ((operand - mean) * (operand - mean));
        front = pop_copy(args);
        i++;
    }

    goto done;

error:
    clear_stack(args);
    *is_bad_formula = 1;
	result = 0.0;
done:
    if (i == 0) {
        i = 1;
        goto error;
    }
    return sqrt(result / (double) i);
}
示例#6
0
double handle_op_sqrt(stack_t **args, int *is_bad_formula)
{
    if (*args == NULL)
        goto error;

    double result = 0.0, operand1;
    char *front;

    // Get first operand
    front = pop_copy(args);
    if (front == NULL)
        goto error;
    operand1 = atof(front, cgc_strlen(front) + 1, is_bad_formula);
    free(front);
    if(*is_bad_formula)
        goto error;

    if (*args != NULL)
        goto error;     // Too many arguments

    if (operand1 < 0)
        goto error;

    result = sqrt(operand1);
    goto done;

error:
    clear_stack(args);
    *is_bad_formula = 1;
	result = 0.0;
done:
    return result;
}
示例#7
0
double handle_op_max(stack_t **args, int *is_bad_formula)
{
    size_t i = 0;
    double max = 0.0;
    if (*args == NULL)
        goto error;

    double operand;
    char *front = pop_copy(args);
    if (front != NULL) {
        max = atof(front, cgc_strlen(front) + 1, is_bad_formula);
        free(front);
        if (*is_bad_formula)
            goto error;
        i++;
    }

    front = pop_copy(args);
    while(front != NULL) {
        operand = atof(front, cgc_strlen(front) + 1, is_bad_formula);
        free(front);
        if(*is_bad_formula)
            goto error;

        if (operand > max)
            max = operand;

        front = pop_copy(args);
        i++;
    }

    goto done;

error:
    clear_stack(args);
    *is_bad_formula = 1;
    max = 0.0;
done:
    if (i == 0) {
        i = 1;
        goto error;
    }
	return max;
}
示例#8
0
static queue_t *infixtorpn(char *infix, size_t size)
{
    /* Use RPN */
    int is_mismatched = 0;
    int func_size = 16;
    int func_idx = -1;
    char *formula = malloc(size);
    int *func_args = malloc(func_size * sizeof(int));

    char *delims = "():,+-*/";
    char *arg, *iter;
    char delim;
    char arith_op[2] = {'\0', '\0'};
    char *value;
    cell_type_e arg_type;
    stack_t *operators = NULL;
    queue_t *output_q = NULL;

    cgc_memcpy(formula, infix, size);
    if (sanitize_formula(formula, size) != 0)
        goto cleanup;

    arg = iter = formula;
    size_t i = 0;
    char prev_char = 0;
    while ( i++ < size) {
        if (strchr(delims, *iter) == NULL && *iter != '\0') {
            prev_char = *iter;
            iter++;
            continue;
        } else if (strchr(delims, *iter) != NULL) {
            if (*iter == '-') {
                if(i <= 1 || (prev_char != ')' && (prev_char < '0' || prev_char > '9'))) {
                    prev_char = *iter;
                    iter++;
                    continue;
                }
            }
        }

        prev_char = *iter;
        delim = *iter;
        *iter = '\0';
        arg_type = parsearg(arg);
        switch (arg_type) {
            case DOUBLE:
            case CELL_ID:
                enqueue_copy(&output_q, arg, cgc_strlen(arg) + 1);
                break;
            case FUNCTION:
#ifdef PATCHED
                if(func_idx == func_size-1) {
#else
                if(func_idx == func_size) {
#endif
                    func_size *= 2;
                    int *temp = realloc(func_args, func_size * sizeof(int));
                    if (temp == NULL)
                        goto error;
                    func_args = temp;
                }

                func_args[++func_idx] = 0;
                push_copy(&operators, arg, cgc_strlen(arg) + 1);
                break;
            case BAD_CELL:
                break;
            default:
                goto error;
        }

        is_mismatched = 0;
        switch(delim) {
            case '(':
                push_copy(&operators, "(", cgc_strlen("(") + 1);
                break;
            case ')':
                is_mismatched = 1;
                while (operators != NULL) {
                    if (strcmp(peek_top(operators), "(") == 0) {
                        value = pop_copy(&operators);
                        free(value);
                        is_mismatched = 0;
                        break;
                    } else {
                        enqueue(&output_q, pop_copy(&operators));
                    }
                }

                // handle parens without any operator
                if (peek_top(operators) == NULL || func_idx < 0)
                    break;

                char num_args_str[16];
                if(strchr(delims, peek_top(operators)[0]) != NULL) {
                    break;
                } else if (parsearg(peek_top(operators)) == FUNCTION) {
                    enqueue_copy(&output_q, itoa(func_args[func_idx--] + 1, num_args_str,
                                    sizeof(num_args_str)), sizeof(num_args_str));
                    enqueue(&output_q, pop_copy(&operators));
                }

                break;
            case ',':
                is_mismatched = 1;
                while (operators != NULL) {
                    if (strcmp(peek_top(operators), "(") == 0) {
                        if (func_idx >= 0)
                            func_args[func_idx]++;
                        is_mismatched = 0;
                        break;
                    } else {
                        enqueue(&output_q, pop_copy(&operators));
                    }
                }
                break;
            case '+':
            case '-':
                //TODO - FIXME - precedence is broken
                //TODO - FIXME - negative is still broken
                // 4/5-5
                arith_op[0] = delim;
                while (operators != NULL) {
                    if (strcmp(peek_top(operators), "-") == 0 || strcmp(peek_top(operators), "+") == 0 ||
                        strcmp(peek_top(operators), "+") == 0 || strcmp(peek_top(operators), "/") == 0)
                        enqueue(&output_q, pop_copy(&operators));
                    else
                        break;
                }

                push_copy(&operators, arith_op, cgc_strlen(arith_op)+1);
                break;
            case '*':
            case '/':
                //TODO - FIXME - precedence is broken
                arith_op[0] = delim;
                while (operators != NULL) {
                    if (strcmp(peek_top(operators), "/") == 0 || strcmp(peek_top(operators), "*") == 0)
                        enqueue(&output_q, pop_copy(&operators));
                    else
                        break;

                }

                push_copy(&operators, arith_op, cgc_strlen(arith_op)+1);
                break;

            case '\0':
                goto finish;
            default:
                goto error;
        }

        if (is_mismatched)
            goto error;

        arg = ++iter;
    }
finish:

    while (operators != NULL) {
        if (strcmp(peek_top(operators), "(") == 0 || strcmp(peek_top(operators), ")") == 0)
            goto error;

        enqueue(&output_q, pop_copy(&operators));
    }

    goto cleanup;

error:
    clear_queue(&output_q);
    clear_stack(&operators);

cleanup:
    free(formula);
    free(func_args);
    return output_q;
}
示例#9
0
static double eval_formula(char *formula, int *is_bad_formula, stack_t **cir_ref, int id)
{
    char val_str[TMP_STR_SIZE];
    char tmp_id_str[TMP_STR_SIZE];
    size_t size = TMP_STR_SIZE;
    double val = 0.0;
    double result = 0.0;
    *is_bad_formula = 0;
    cell_type_e cell_type;
    char *arg;

    if(itoa(id, tmp_id_str, size) == NULL)
        goto error;

    push_copy(cir_ref, tmp_id_str, cgc_strlen(tmp_id_str) + 1);
    queue_t *rpn = infixtorpn(formula, cgc_strlen(formula) + 1);

    queue_t *args = NULL;
    stack_t *values = NULL;

    stack_t *tmp = NULL;
    operator_t *op = NULL;

    while (rpn != NULL) {
        arg = dequeue_copy(&rpn);
        cell_type = parsearg(arg);
        switch(cell_type) {
            case DOUBLE:
                push(&values, arg);
                break;
            case FUNCTION:
                op = get_op(arg);
                if (eval_function(op, &values, val_str, size) == -1) {
                    goto error;
                }

                push_copy(&values, val_str, size);
                break;
            case CELL_ID:
                tmp = *cir_ref;
                cell_t *cell = get_cell(arg);
                if(cell == NULL)
                    goto error;

                while (tmp != NULL) {
                    if(itoa(cell->id, tmp_id_str, size) == NULL)
                        goto error;

                    if (memcmp(tmp->data, tmp_id_str, cgc_strlen(tmp->data) + 1) == 0)
                        goto error; //Circular reference
                    tmp = tmp->next;
                }

                if (cell->cell_type == UNUSED) {
                    push_copy(&values, "0", sizeof("0"));
                } else if (cell->cell_type == DOUBLE) {
                    push_copy(&values, cell->str, cgc_strlen(cell->str) + 1);
                } else if(cell->cell_type == FORMULA) {
                    val = eval_formula(cell->formula, is_bad_formula, cir_ref, cell->id);
                    if(*is_bad_formula)
                        goto error;

                    ftoa(val, val_str, size);
                    push_copy(&values, val_str, size);
                } else {
                    goto error;
                }

                break;
            default:
                goto error;
        }
    }

    char *result_str = pop_copy(&values);
    if (values != NULL)
        goto error;

    result = atof(result_str, size, is_bad_formula);
    if (*is_bad_formula)
        goto error;

    goto cleanup;

error:
    *is_bad_formula = 1;
    val = 0.0;
    clear_queue(&rpn);
    clear_queue(&args);
    clear_stack(&values);
cleanup:
    free(pop_copy(cir_ref));

    return result;
}
示例#10
0
文件: sh_MT.cpp 项目: hi-brain/sh_MT
RTC::ReturnCode_t sh_MT::onExecute(RTC::UniqueId ec_id)
{
	if(!m_input2In.isNew()){
		return RTC::RTC_OK;
	}
	m_input2In.read();
	
	//データの復元
	printf("データの復元_インデックスの読み込み(MT)\n");
	double c = m_input2.pop_length;//18522
	double d = m_input2.pop_width;//28
	printf("pop_x = %f	pop_y = %f	\n", c, d);//popのインデックス

	double a = m_input2.ind_length;//2
	double b = m_input2.ind_width;//4
	printf("ind_x = %f	ind_y = %f	\n", a, b);//indのインデックス
		
	printf("データの復元_popの読み込み(MT)\n");
	double test=0;
	int num = 0;

	mwArray pop_copy(18522, 28, mxDOUBLE_CLASS);//pop_copyの入れ物の型宣言
	///////////////////////////////////////////////////////////
	double *data_copy_pop = new double [m_input2.pop_length * m_input2.pop_width];
	
	for (num = 0; num < m_input2.pop_length * m_input2.pop_width ; num++) {
		data_copy_pop[num] = m_input2.pop[num];
	}

	pop_copy.SetData(data_copy_pop, m_input2.pop_length * m_input2.pop_width);//pop
	///////////////////////////////////////////////////////////

	printf("データの復元_indの読み込み(MT)\n");
		
	mwArray ind_copy(m_input2.ind_length, m_input2.ind_width, mxDOUBLE_CLASS);
	///////////////////////////////////////////////////////////
	double *data_copy_ind = new double [m_input2.pop_length * m_input2.pop_width];
	for (num = 0; num < m_input2.ind_length * m_input2.ind_width ; num++) {
		data_copy_ind[num] = m_input2.ind[num];
	}

	ind_copy.SetData(data_copy_ind, m_input2.ind_length * m_input2.ind_width);//ind
	///////////////////////////////////////////////////////////
		
	//pop,indの復元が終わったはず
	printf("復元完了(MT)\n");

	///////////////////////////////////////////////////////////
	//デフォルトパラメータの読み込み
	mwArray pars;
	shPars(1, pars);//デフォルトパラメータを.matから読み込みparsに入れる
	///////////////////////////////////////////////////////////

	///////////////////////////////////////////////////////////
	//SHmodel本体_MT

	//MT野の処理
	mwArray output(1, 2, mxCELL_CLASS);//出力の入れ物
		
	mwArray pop = pop_copy;
	mwArray ind = ind_copy;

	printf("モデル本体の処理開始(MT)\n");

	mwArray inputMT_a(1, 3, mxCELL_CLASS);//出力の入れ物
	inputMT_a.Get(1,1).Set(pop);//
	inputMT_a.Get(1,2).Set(ind);//
	inputMT_a.Get(1,3).Set(pars);//
	shModelMtLinear(2, output, inputMT_a);

	pop = output.Get(2, 1, 1); 
	ind = output.Get(2, 1, 2);
	printf("MT野の処理shModelMtLinear終了(MT)\n");

	mwArray inputMT_b(1, 3, mxCELL_CLASS);//出力の入れ物
	inputMT_b.Get(1,1).Set(pop);//
	inputMT_b.Get(1,2).Set(ind);//
	inputMT_b.Get(1,3).Set(pars);//
	shModelMtPreThresholdBlur(2, output, inputMT_b);

	pop = output.Get(2, 1, 1); 
	ind = output.Get(2, 1, 2);
	printf("MT野の処理shModelMtPreThresholdBlur終了(MT)\n");

	mwArray inputMT_c(1, 3, mxCELL_CLASS);//出力の入れ物
	inputMT_c.Get(1,1).Set(pop);//
	inputMT_c.Get(1,2).Set(ind);//
	inputMT_c.Get(1,3).Set(pars);//
	shModelHalfWaveRectification(2, output, inputMT_c);

	pop = output.Get(2, 1, 1); 
	ind = output.Get(2, 1, 2);
	printf("MT野の処理shModelHalfWaveRectification終了(MT)\n");

	mwArray inputMT_d(1, 3, mxCELL_CLASS);//出力の入れ物
	inputMT_d.Get(1,1).Set(pop);//
	inputMT_d.Get(1,2).Set(ind);//
	inputMT_d.Get(1,3).Set(pars);//
	shModelMtPostThresholdBlur(2, output, inputMT_d);

	pop = output.Get(2, 1, 1); 
	ind = output.Get(2, 1, 2);
	printf("MT野の処理shModelMtPostThresholdBlur終了(MT)\n");

	mwArray inputMT_e(1, 3, mxCELL_CLASS);//出力の入れ物
	inputMT_e.Get(1,1).Set(pop);//
	inputMT_e.Get(1,2).Set(ind);//
	inputMT_e.Get(1,3).Set(pars);//

	mwArray outputMT(1, 4, mxCELL_CLASS);//出力の入れ物
	mwArray nume;
	mwArray deno;
	
	shModelMtNormalization(4, outputMT, inputMT_e);

	printf("MT野の処理shModelMtNormalization終了(MT)\n");

	//計算結果の表示(仮)
	a =0;

	//////////////////////////////////////////////////////////////
	printf("\npop(MT)\n");
	mwArray pop2(outputMT.Get(2, 1, 1));//popの確保(2, 1, 2)がind_outputMT
	printf("NumberOfDimensions(MT) : %d\n", pop2.NumberOfDimensions());

	mwArray pop2_dims = pop2.GetDimensions();
	int pop2_dim1 =  pop2_dims.Get(1, 1);//int型に変換する必要あり
	int pop2_dim2 =  pop2_dims.Get(1, 2);
	printf("1 : (MT)%d\n", pop2_dim1);//378
	printf("2 : (MT)%d\n", pop2_dim2);//19

	printf("NumberOfElements(MT) : %d\n", pop2.NumberOfElements());

	for(int y = 1; y <= pop2_dim2; y++) {
		for(int x = 1; x <= pop2_dim1; x++) {
			//縦長に保存されている
			a = pop2.Get((mwSize)2, x, y);//mwArrayの呼び出し
		}
	}
	printf("pop_last(MT) = %f\n", a);
	printf("\n");
	///////////////////////////////////////////////////////////////

	///////////////////////////////////////////////////////////////
	printf("ind(MT)\n");
	mwArray ind2(outputMT.Get(2, 1, 2));//indの確保_outputMT
	printf("NumberOfDimensions(MT) : %d\n", ind2.NumberOfDimensions());

	mwArray ind2_dims = ind2.GetDimensions();
	int ind2_dim1 =  ind2_dims.Get(1, 1);//int型に変換する必要あり
	int ind2_dim2 =  ind2_dims.Get(1, 2);
	printf("1 : (MT)%d\n", ind2_dim1);//378
	printf("2 : (MT)%d\n", ind2_dim2);//19

	printf("NumberOfElements(MT) : %d\n", ind2.NumberOfElements());

	for(int y = 1; y <= ind2_dim2; y++) {
		//printf("\n");
		for(int x = 1; x <= ind2_dim1; x++) {
			a = ind2.Get((mwSize)2, x, y);//mwArrayの呼び出し
			printf("%f ", a);	
		}
		printf("\n");
	}
	printf("\n");
	///////////////////////////////////////////////////////////////

	//出力部分
	m_output2.pop_length = pop2_dim1;/////////////////////
	m_output2.pop_width = pop2_dim2;/////////////////////////

	m_output2.pop.length(pop2_dim1 * pop2_dim2);//popの配列の確保
		
	num = 0;
	double *data_copy_pop2 = new double [pop2_dim1 * pop2_dim2];
	pop.GetData(data_copy_pop2, pop2_dim1 * pop2_dim2);

	for (num = 0; num < pop2_dim1 * pop2_dim2 ; num++) {
		m_output2.pop[num] = data_copy_pop2[num];
	}

	//ind_2*4/
	m_output2.ind_length = ind2_dim1;////////////////
	m_output2.ind_width = ind2_dim2;/////////////////

	m_output2.ind.length(ind2_dim1 * ind2_dim2);//popの配列の確保
		
	double *data_copy_ind2 = new double [ind2_dim1 * ind2_dim2];
	ind.GetData(data_copy_ind2, ind2_dim1 * ind2_dim2);

	for (num = 0; num < ind2_dim1 * ind2_dim2; num++) {
		m_output2.ind[num] = data_copy_ind2[num];
	}

	m_output2Out.write();//書き出し_異常発生の場合接続カット

	///////////////////////////////////////////////////////////////////////////////////////////////////////

	printf("MT_end\n");
	delete[] data_copy_pop;//data_copyのデリート
	delete[] data_copy_ind;
	
	return RTC::RTC_OK;
}
示例#11
0
// Selection implementation.
std::vector<std::pair<population::size_type,std::vector<population::individual_type>::size_type> >
hv_fair_r_policy::select(const std::vector<population::individual_type> &immigrants, const population &dest) const
{
    // Fall back to fair_r_policy when facing a single-objective problem.
    if (dest.problem().get_f_dimension() == 1) {
        return fair_r_policy(m_rate, m_type).select(immigrants, dest);
    }

    std::vector<population::individual_type> filtered_immigrants;
    filtered_immigrants.reserve(immigrants.size());

    // Keeps information on the original indexing of immigrants after we filter out the duplicates
    std::vector<unsigned int> original_immigrant_indices;
    original_immigrant_indices.reserve(immigrants.size());

    // Remove the duplicates from the set of immigrants
    std::vector<population::individual_type>::iterator im_it = (const_cast<std::vector<population::individual_type> &>(immigrants)).begin();
    unsigned int im_idx = 0;
    for( ; im_it != immigrants.end() ; ++im_it) {
        decision_vector im_x((*im_it).cur_x);

        bool equal = true;
        for ( unsigned int idx = 0 ; idx < dest.size() ; ++idx ) {
            decision_vector isl_x(dest.get_individual(idx).cur_x);
            equal = true;
            for (unsigned int d_idx = 0 ; d_idx < im_x.size() ; ++d_idx) {
                if (im_x[d_idx] != isl_x[d_idx]) {
                    equal = false;
                    break;
                }
            }
            if (equal) {
                break;
            }
        }
        if (!equal) {
            filtered_immigrants.push_back(*im_it);
            original_immigrant_indices.push_back(im_idx);
        }
        ++im_idx;
    }

    // Computes the number of immigrants to be selected (accounting for the destination pop size)
    const population::size_type rate_limit = std::min<population::size_type>(get_n_individuals(dest), boost::numeric_cast<population::size_type>(filtered_immigrants.size()));

    // Defines the retvalue
    std::vector<std::pair<population::size_type, std::vector<population::individual_type>::size_type> > result;

    // Skip the remaining computation if there's nothing to do
    if (rate_limit == 0) {
        return result;
    }

    // Makes a copy of the destination population
    population pop_copy(dest);

    // Merge the immigrants to the copy of the destination population
    for (population::size_type i  = 0; i < rate_limit; ++i) {
        pop_copy.push_back(filtered_immigrants[i].cur_x);
    }

    // Population fronts stored as indices of individuals.
    std::vector< std::vector<population::size_type> > fronts_i = pop_copy.compute_pareto_fronts();

    // Population fronts stored as fitness vectors of individuals.
    std::vector< std::vector<fitness_vector> > fronts_f (fronts_i.size());

    // Nadir point is established manually later, first point is a first "safe" candidate.
    fitness_vector refpoint(pop_copy.get_individual(0).cur_f);

    // Fill fronts_f with fitness vectors and establish the nadir point
    for (unsigned int f_idx = 0 ; f_idx < fronts_i.size() ; ++f_idx) {
        fronts_f[f_idx].resize(fronts_i[f_idx].size());
        for (unsigned int p_idx = 0 ; p_idx < fronts_i[f_idx].size() ; ++p_idx) {
            fronts_f[f_idx][p_idx] = fitness_vector(pop_copy.get_individual(fronts_i[f_idx][p_idx]).cur_f);

            // Update the nadir point manually for efficiency.
            for (unsigned int d_idx = 0 ; d_idx < fronts_f[f_idx][p_idx].size() ; ++d_idx) {
                refpoint[d_idx] = std::max(refpoint[d_idx], fronts_f[f_idx][p_idx][d_idx]);
            }
        }
    }

    // Epsilon is added to nadir point
    for (unsigned int d_idx = 0 ; d_idx < refpoint.size() ; ++d_idx) {
        refpoint[d_idx] += m_nadir_eps;
    }

    // Vector for maintaining the original indices of points for augmented population as 0 and 1
    std::vector<unsigned int> g_orig_indices(pop_copy.size(), 1);

    unsigned int no_discarded_immigrants = 0;

    // Store which front we process (start with the last front) and the number of processed individuals.
    unsigned int front_idx = fronts_i.size(); // front_idx is equal to the size, since it's decremented right in the main loop
    unsigned int processed_individuals = 0;

    // Pairs of (islander index, islander exclusive hypervolume)
    // Second item is updated later
    std::vector<std::pair<unsigned int, double> > discarded_islanders;

    std::vector<std::pair<unsigned int, double> > point_pairs;
    // index of currently processed point in the point_pair vector.
    // Initiated to its size (=0) in order to enforce the initial computation on penultimate front.
    unsigned int current_point = point_pairs.size();

    // Stops when we reduce the augmented population to the size of the original population or when the number of discarded islanders reaches the limit
    while (processed_individuals < filtered_immigrants.size() && discarded_islanders.size() < rate_limit) {

        // if current front was exhausted, load next one
        if (current_point == point_pairs.size()) {
            --front_idx;

            // Compute contributions
            std::vector<double> c;

            // If there exist a dominated front for front at index front_idx
            if (front_idx + 1 < fronts_f.size()) {
                std::vector<fitness_vector> merged_front;
                // Reserve the memory and copy the fronts
                merged_front.reserve(fronts_f[front_idx].size() + fronts_f[front_idx + 1].size());

                copy(fronts_f[front_idx].begin(), fronts_f[front_idx].end(), back_inserter(merged_front));
                copy(fronts_f[front_idx + 1].begin(), fronts_f[front_idx +1].end(), back_inserter(merged_front));

                hypervolume hv(merged_front, false);
                c = hv.contributions(refpoint);
            } else {
                hypervolume hv(fronts_f[front_idx], false);
                c = hv.contributions(refpoint);
            }

            // Initiate the pairs and sort by second item (exclusive volume)
            point_pairs.resize(fronts_f[front_idx].size());
            for(unsigned int i = 0 ; i < fronts_f[front_idx].size() ; ++i) {
                point_pairs[i] = std::make_pair(i, c[i]);
            }
            current_point = 0;
            std::sort(point_pairs.begin(), point_pairs.end(), sort_point_pairs_asc);
        }

        unsigned int orig_lc_idx = fronts_i[front_idx][point_pairs[current_point].first];

        if (orig_lc_idx < dest.size()) {
            discarded_islanders.push_back(std::make_pair(orig_lc_idx, 0.0));
        } else {
            ++no_discarded_immigrants;
        }

        // Flag given individual as discarded
        g_orig_indices[orig_lc_idx] = 0;

        ++processed_individuals;
        ++current_point;
    }

    // Number of non-discarded immigrants
    unsigned int no_available_immigrants = boost::numeric_cast<unsigned int>(filtered_immigrants.size() - no_discarded_immigrants);

    // Pairs of (immigrant index, immigrant exclusive hypervolume)
    // Second item is updated later
    std::vector<std::pair<unsigned int, double> > available_immigrants;
    available_immigrants.reserve(no_available_immigrants);
    for(unsigned int idx = dest.size() ; idx < pop_copy.size() ; ++idx) {
        // If the immigrant was not discarded add it to the available set
        if ( g_orig_indices[idx] == 1 ) {
            available_immigrants.push_back(std::make_pair(idx, 0.0));
        }
    }

    // Aggregate all points to establish the hypervolume contribution of available immigrants and discarded islanders
    std::vector<fitness_vector> merged_fronts;
    merged_fronts.reserve(pop_copy.size());

    for(unsigned int idx = 0 ; idx < pop_copy.size() ; ++idx) {
        merged_fronts.push_back(pop_copy.get_individual(idx).cur_f);
    }

    hypervolume hv(merged_fronts, false);
    std::vector<std::pair<unsigned int, double> >::iterator it;

    for(it = available_immigrants.begin() ; it != available_immigrants.end() ; ++it) {
        (*it).second = hv.exclusive((*it).first, refpoint);
    }

    for(it = discarded_islanders.begin() ; it != discarded_islanders.end() ; ++it) {
        (*it).second = hv.exclusive((*it).first, refpoint);
    }

    // Sort islanders and immigrants according to exclusive hypervolume
    sort(available_immigrants.begin(), available_immigrants.end(), hv_fair_r_policy::ind_cmp);
    sort(discarded_islanders.begin(), discarded_islanders.end(), hv_fair_r_policy::ind_cmp);

    // Number of exchanges is the minimum of the number of non discarded immigrants and the number of discarded islanders
    unsigned int no_exchanges = std::min(boost::numeric_cast<unsigned int>(available_immigrants.size()), boost::numeric_cast<unsigned int>(discarded_islanders.size()));

    it = available_immigrants.begin();
    std::vector<std::pair<unsigned int, double> >::reverse_iterator r_it = discarded_islanders.rbegin();

    // Match the best immigrant (forward iterator) with the worst islander (reverse iterator) no_exchanges times.
    for(unsigned int i = 0 ; i < no_exchanges ; ++i) {
        // Break if any islander is better than an immigrant
        if ((*r_it).second > (*it).second) {
            break;
        }
        // Push the pair (islander_idx, fixed_immigrant_idx) to the results
        result.push_back(std::make_pair((*r_it).first, original_immigrant_indices[(*it).first - dest.size()]));
        ++r_it;
        ++it;
    }

    return result;
}
示例#12
0
double handle_op_median(stack_t **args, int *is_bad_formula)
{
    size_t i = 0;
    stack_t *sorted, *tmp, *prev;
#ifdef PATCHED
    sorted = NULL;
#endif
    if (*args == NULL)
        goto error;
    sorted = NULL;

    double median = 0.0, operand, temp;
    char *front = pop_copy(args);

    operand = atof(front, cgc_strlen(front) + 1, is_bad_formula);
    if(*is_bad_formula) {
        free(front);
        goto error;
    } else {
        push(&sorted, front);
        i++;
    }

    front = pop_copy(args);
    while(front != NULL) {
        operand = atof(front, cgc_strlen(front) + 1, is_bad_formula);
        if(*is_bad_formula)
            goto error;

        //using stack as linked list
        tmp = sorted;
        int passed_first = 0, is_inserted = 0;
        stack_t *elem = NULL;
        while (tmp != NULL) {
            temp = atof(tmp->data, cgc_strlen(tmp->data) + 1, is_bad_formula);
            if (operand <= temp) {
                if (!passed_first) {
                    push(&sorted, front);
                } else {
                    elem = malloc(sizeof(stack_t));
                    elem->data = front;
                    elem->next = tmp;
                    prev->next = elem;
                }
                is_inserted = 1;
                break;
            } else {
                prev = tmp;
                tmp = tmp->next;
                passed_first++;
            }
        }
        if (!is_inserted) {
            tmp = sorted;
            while (tmp->next != NULL)
                tmp = tmp->next;

            elem = malloc(sizeof(stack_t));
            elem->data = front;
            elem->next = NULL;
            tmp->next = elem;
        }

        front = pop_copy(args);
        i++;
    }

    tmp = sorted;
    int j = 0;
    if (i % 2 == 0) {
        for(j = 0; j < (i / 2) - 1; j++)
            tmp = tmp->next;

        median += atof(tmp->data, cgc_strlen(tmp->data) + 1, is_bad_formula);
        tmp = tmp->next;
        median += atof(tmp->data, cgc_strlen(tmp->data) + 1, is_bad_formula);

        median /= 2;
    } else {
        for(j = 0; j < (i / 2); j++)
            tmp = tmp->next;

        median += atof(tmp->data, cgc_strlen(tmp->data) + 1, is_bad_formula);
    }

    goto done;

error:
    clear_stack(args);
    *is_bad_formula = 1;
    median = 0.0;
done:
    if (i == 0) {
        i = 1;
        goto error;
    }
    clear_stack(&sorted);
	return median;
}