Example #1
0
VectorXd lsq_weigh_nonneg(const MatrixXd& A, const VectorXd& b, const VectorXd& w)
{
	const unsigned m = A.rows();
	const unsigned n = A.cols();
	if(b.size() != m || w.size() != m || n < 1 || m < 1)
	{
		std::cerr<<"#error in lsq_weigh_nonneg: If A is a m by n matrix, then b and w must have length m. We also want n >= 1 and m >= 1. A is "<< m <<" by "<< n <<", b has length "<< b.size() <<" and w has length "<< w.size() <<"."<<std::endl;
		throw std::invalid_argument("lsq_weigh_nonneg: dimension mismatch");
	}
	
	// initialization
	const MatrixXd H = A.transpose() * w.asDiagonal() * A;
	const VectorXd f = - A.transpose() * w.asDiagonal() * b;
	VectorXd x = VectorXd::Zero(n), mu = f;
	
	// iterate
	double relerr;
	do
	{
		for(unsigned k = 0; k < n; ++k)
		{
			const double xtmp = x(k);
			x(k) -= mu(k) / H(k,k);
			if(x(k) < 0) x(k) = 0;
			const double d = x(k) - xtmp;
			if(d != 0) mu += d * H.col(k);
		}
		
		relerr = 0;
		for(unsigned k = 0; k < n; ++k)
		{
			if(x(k) != 0)
			{
				double err = mu(k) / x(k);
				if(err < 0) err = -err;
				if(err > relerr) relerr = err;
			}
		}
	}
	while(relerr >= 1e-2);
	
	// update non-zero columns with more costly, but also more precise calculation
	const VectorXi p = find(x.array() > 0);
	const VectorXd xp = lscov(pick_col(A, p), b, w);
	if(find(xp.array() >= 0).all()) set_ind(x, p, xp);
	
	return x;
}
Example #2
0
int sim_ann_v1(int n, int k, int* object, int old_k, int* old_object, int num_iterations, double initial_temp, double cool_rate)
{
	int h = n*n;
	// copy of the best found object
	int* best_object = malloc(sizeof(int)*h*(k));
	int min_found_cost=0;
	
  	// evaluate the existing object
    int total = (k)*(k-1)/2;
    int* cv = malloc(sizeof(int)*total*h);
    int* missing = malloc(sizeof(int)*(k+old_k));
    
    // addition: cost vector with old_object
    int* old_cv;
    if (old_k > 0)
    {
        old_cv = malloc(sizeof(int)*old_k*k*h);
        // addition: initialize the old_cv, and adjust num_missing
        old_cost_vector(n, k, object, old_k, old_object, old_cv);
    }
    
    cost_vector(n, k, object, cv);
    num_missing(n, k, cv, old_k, old_cv, missing);
    
	copy_array(h*(k), object, best_object);
	for(int c=0; c<k+old_k; c++) min_found_cost += missing[c];
	min_found_cost = min_found_cost/2;
//	printf("missing: ");
//    print_int_matrix(missing, 1, k, stdout);
//	printf("min found cost=%d \n", min_found_cost);
//	printf("old cv: \n");
//	print_int_matrix(old_cv, h, k*old_k, stdout);
//	printf("cv: \n");
//	print_int_matrix(cv, h, total, stdout);
	
	int min_cost;
	int max_cost;
	int col, row11, row12, row21, row22, row1, row2;
	int total_cost1, total_cost2, total_cost;
	int swap;
	int curr_cost = min_found_cost;
	double current_temp = initial_temp;
	int good;

	// build index matrix 
	int* idx_mat = malloc(sizeof(int)*(k)*(k));
	int count = 0;
	for(int c1=0; c1<k; c1++)
	{
		idx_mat[c1*(k)+c1] = -1;
		for(int c2=c1+1; c2<k; c2++)
		{	
			idx_mat[c1*(k)+c2] = count;
			idx_mat[c2*(k)+c1] = count;
			count ++;
		}
	}
	long unsigned iter=0;
    while(iter<num_iterations && min_found_cost>0) //(curr_cost > 0) 
    {
        // evaluate the current object and find min and max costs
        min_cost = h*(k+old_k);
        max_cost = 0;
        for(int c=0; c<k; c++)
        {
            if(min_cost>missing[old_k+c]) min_cost=missing[old_k+c];
            if(max_cost<missing[old_k+c]) max_cost=missing[old_k+c];
        }
        
        
        // pick a random (with priority) column
        col = pick_col(old_k, k, missing, min_cost, max_cost);

		row11 = rand()%h;
		row12 = row11;
		while(row12 == row11) row12 = rand()%h;
		
		row21 = rand()%h;
		row22 = row21;
		while(row22 == row21) row22 = rand()%h;
		
		//printf("column = %d \n", col);
		//printf("first choice of rows: %d, %d \n", row11, row12);	
		//printf("second choice of rows: %d, %d \n", row21, row22);	
		total_cost1 = swap_cost(row11, row12, col, n, k, object, cv, idx_mat, old_k, old_object, old_cv);
		total_cost2 = swap_cost(row21, row22, col, n, k, object, cv, idx_mat, old_k, old_object, old_cv);
		//printf("total_cost1 = %d, total_cost2=%d \n", total_cost1, total_cost2);
        

        if(total_cost1<total_cost2)
        {
            total_cost = total_cost1;
			row1 = row11;
			row2 = row12;
        }
        else
        {
            total_cost = total_cost2;
            row1 = row21;
			row2 = row22;
        }
        
        
        good=0;
        if(total_cost <= 0) good=1;
        else if(acceptance_prob(total_cost,  current_temp)> ( ((double)rand())/ ((double)RAND_MAX+1) )) 
        {
            good=1; 
            current_temp = current_temp*cool_rate;
            if(current_temp < 0.0001) current_temp=0.0001;
        }
        
        
        if(good==1)
        {
        
        	// make changes to cv and missing
            make_adjustments(col, row1, row2, n,k, object, cv, old_k, old_object, old_cv, missing, idx_mat);
            
            // accept swap
            swap = object[col*h+row1];
            object[row1+col*h] = object[row2+col*h];
            object[row2+col*h] = swap;
            curr_cost += total_cost;

            if(min_found_cost>curr_cost)
            {
                min_found_cost=curr_cost;
                copy_array(h*(k), object, best_object);
                //printf("new_cost=%d  \n", curr_cost);
            }
            //printf("total_cost = %d new cost = %d iter=%lu \n", total_cost, curr_cost, iter);
            //printf("current array: \n");
            //print_int_matrix(object, h, k, stdout);
            //printf("cv: \n");
            //print_int_matrix(cv, h, total, stdout);
            //printf("missing: ");
            //print_int_matrix(missing, 1, k+old_k, stdout);
            //printf("\n\n");
        }
        
        iter++;
        //if(iter%1000==0) printf("iter=%lu \n", iter);
    }
	


    free(idx_mat);
    free(cv);
    if (old_k > 0)
    {
        free(old_cv);
    }
    free(missing);
    copy_array(h*(k), best_object, object);
    free(best_object);
    
    return min_found_cost;
}