Esempio n. 1
0
/**
 * Check if the problem have less of 100.000 permutation if it's the case we use the naive algorithm
**/
bool is_easy_solution(const int k, const int n)
{
	double fn, fk, fnk, ll, bino;
	fn = stirling_approx(n);
	fk = stirling_approx(k);
	fnk = stirling_approx(n-k);
	ll = log(100000); // limit heristic
	bino = fn - fk - fnk;
	int binomial = binomial_coef(n,k);
	if (n <= 1) { return true; }
	else {
		return bino *0.95 <= ll;
	}	
}
Esempio n. 2
0
/* citrunc: truncate ci expansion
 * -------------------------------------------------------------------
 * Input:
 *  aelec = alpha electrons
 *  belec = beta  electrons
 *  orbs  = orbitals
 *  nfrzc = number of frozen core orbitals
 *  ndocc = number of doubly-occupied orbitals
 *  nactv = number of active orbitals
 *  nfrzv = number of frozen virtual orbitals
 *  xlvl  = excitation level
 * Output:
 *  astr_len = number of alpha strings
 *  bstr_len = number of beta  strings
 *  dtrm_len = number of determinants */
int citrunc(int aelec, int belec, int orbs, int nfrzc, int ndocc,
	    int nactv, int nfrzv, int xlvl, int *astr_len,
	    int *bstr_len, int *dtrm_len)
{
	/* output scalar 
	 * err = error handling */
	int err;
	
	/* local scalars 
	 * ci_orbs  = orbitals - (frozen core) - (frozen virtual)
	 * ci_aelec = aelec - (frozen core)
	 * ci_belec = belec - (frozen core)
	 * axdocc   = alpha string docc   orbital excitations
	 * axactv   = alpha string active orbital excitations
	 * bxdocc   = beta  string docc   orbital excitations
	 * bxactv   = beta  string active orbital excitations
	 * astrings = binomial_coef(ci_orbs, ci_aelec)
	 * bstrings = binomial_coef(ci_orbs, ci_belec)
	 * tot_dets = astrings * bstrings 
	 * aindx    = alpha string index
	 * bindx    = beta  string index */
	int  ci_orbs, ci_aelec, ci_belec;
	int   axdocc,   axactv,   bxdocc,  bxactv;
	int astrings, bstrings, tot_dets;
	int aindx, bindx;
	
	/* local arrays 
	 * astr1      = alpha string 1
	 * astr2      = alpha string 2
	 * bstr1      = beta  string 1
	 * bstr2      = beta  string 2 
	 * bstr_hf    = beta  string start (Hartree-Fock)
	 * astr_hf    = alpha string start (Hartree-Fock)
	 * detlstfl   = determinant list file name
	 * strlstfl   = string list file name  */
	int *astr1, *astr2, *bstr1, *bstr2, *bstr_hf, *astr_hf;
	char detlstfl[FLNMSIZE], strlstfl[FLNMSIZE];
	
	/* local linked-list
	 * qindxlist = valid beta strings
         * pindxlist = valid alpha strings
         * detlist   = valid determinants */
	struct validstr *qindxlist;
	struct validstr *qptr, *tmp;
        struct validstr *pindxlist;
        struct validstr *pptr;
        struct validdet *detlist;
        struct validdet *dptr;
	
	/* local files
	 * detfileptr = determinant list file pointer
	 * strfileptr = string list file pointer */
	FILE *detfileptr, *strfileptr;
	
	int i, j;
	
	/* initialize error flag */
	err = 0;
	/* set determinant and string list file names */
	strncpy(detlstfl, "det.list", FLNMSIZE);
	strncpy(strlstfl, "str.list", FLNMSIZE);
	
	/* compute electron numbers in truncated space */
	ci_aelec = aelec - nfrzc;
	ci_belec = belec - nfrzc;
	ci_orbs  = orbs - nfrzc - nfrzv;
	
	fprintf(stdout, " CI Expansion: %d %d %d\n", ci_aelec, ci_belec, ci_orbs);
	
	/* check input */
	/* ndocc values */
	if (ndocc > ci_belec) {
		fprintf(stderr,
			"*** ERROR: Unoccupied DOCC orbitals! ***\n");
		err = -100;
		return err;
	}
	if (ci_orbs == 0 ) {
		fprintf(stderr,
			"WARNING: No virtual orbitals!\n");
		err = 10;
		return err;
	}
	
	/* compute total, untruncated - excepting frozen core truncation -
	 * number of alpha/beta/determinant strings */
	astrings = binomial_coef(ci_orbs, ci_aelec);
	bstrings = binomial_coef(ci_orbs, ci_belec);
	tot_dets = astrings * bstrings;
	fprintf(stdout, "Untruncated expansion size = %10d\n", tot_dets);
	
	/* allocate arrays */
	astr1 = (int *) malloc(ci_aelec * sizeof(int));
	astr2 = (int *) malloc(ci_aelec * sizeof(int));
	bstr1 = (int *) malloc(ci_belec * sizeof(int));
	bstr2 = (int *) malloc(ci_belec * sizeof(int));
	astr_hf = (int *) malloc(ci_aelec * sizeof(int));
	bstr_hf = (int *) malloc(ci_belec * sizeof(int));
	
	/* form HF strings */
	for (i = 0; i < ci_aelec; i++) {
		astr_hf[i] = i + 1;
		astr1[i] = i + 1;
	}
	for (i = 0; i < ci_belec; i++) {
		bstr_hf[i] = i + 1;
		bstr1[i] = i + 1;
	}
	
	/* open determinant list file */
	detfileptr = fopen("det.list", "w");
	if (detfileptr == NULL) {
		fprintf(stderr,
			"*** ERROR: det.list could not be opened! ***\n");
		exit(1);
	}
	/* open string list file */
	strfileptr = fopen("str.list", "w");
	if (strfileptr == NULL) {
		fprintf(stderr,
			"*** ERROR: str.list could not be opened! ***\n");
		exit(1);
	}
	
	/* first strings are included */
	aindx = str_adrfind(astr1, ci_aelec, ci_orbs);
	bindx = str_adrfind(bstr1, ci_belec, ci_orbs);
	fprintf(detfileptr, " %14d %14d\n", aindx, bindx);
	fprintf(strfileptr, "BETA\n");
	fprintf(strfileptr, " %14d\n", bindx);
	
	*astr_len = 1;
	*bstr_len = 1;
	*dtrm_len = 1;
	
	/* allocate first node of valid q string linked list */
	qindxlist = malloc(sizeof(struct validstr));
	qindxlist->next = NULL;
	qptr = qindxlist;
	
	qptr->index = bindx;
	qptr->xdocc = 0;
	qptr->xactv = 0;
	
	qptr->next = malloc(sizeof(struct validstr));
	qptr->next->next = NULL;
	qptr = qptr->next;
        
	/* allocate first node of valid p string linked list */
	pindxlist = malloc(sizeof(struct validstr));
	pindxlist->next = NULL;
	pptr = pindxlist;
	
	pptr->index = aindx;
	pptr->xdocc = 0;
	pptr->xactv = 0;
	
	pptr->next = malloc(sizeof(struct validstr));
	pptr->next->next = NULL;
	pptr = pptr->next;

        /* allocate first node of valid determinant list */
        detlist = malloc(sizeof(struct validdet));
        detlist->next = NULL;
        dptr = detlist;
        dptr->pindx = 1;
        dptr->qindx = 1;
        dptr->next = malloc(sizeof(struct validdet));
        dptr->next->next = NULL;
        dptr = dptr->next;
        
	/* first loop: |p,q> for p=1; q=1,..,bstrings */
	for (i = 2; i <= bstrings; i++) {
		/* generate beta electron string */
		str_strfind1(bstr1, ci_belec, ci_orbs, bstr2);
		
		/* test docc restrictions */
		bxdocc = str_enfdocc(bstr2, ci_belec, ndocc, nactv);
		if (bxdocc > xlvl) {
			for (j = 0; j < ci_belec; j++) {
				bstr1[j] = bstr2[j];
			}
			continue;
		}
		
		/* test active orbital restrictions */
		bxactv = str_enfactv(bstr2, ci_belec, ndocc, nactv);
		if (bxactv > xlvl) {
			for (j = 0; j < ci_belec; j++) {
				bstr1[j] = bstr2[j];
			}
			continue;
		}
		
		/* if here, string is valid */
		*bstr_len = *bstr_len + 1;
		//fprintf(strfileptr, " %14d\n", i);
		
		*dtrm_len = *dtrm_len + 1;
                dptr->pindx = 1;
                dptr->qindx = i;
                //fprintf(detfileptr, " %14d %14d\n", 1, i);
		dptr->next = malloc(sizeof(struct validdet));
                dptr->next->next = NULL;
                dptr = dptr->next;
                
		qptr->index = i;
		qptr->xdocc = bxdocc;
		qptr->xactv = bxactv;
		
		qptr->next = malloc(sizeof(struct validstr));
		qptr->next->next = NULL;
		qptr = qptr->next;
		
		/* increment string */
		for (j = 0; j < ci_belec; j++) {
			bstr1[j] = bstr2[j];
		}
		
	}
	
	/* second loop: |p,q> for p=1,..,astrings; q=1,..,bstrings */
	fprintf(strfileptr, "ALPHA\n");
	fprintf(strfileptr, " %14d\n", aindx);
	for (i = 2; i <= astrings; i++) {
		
		/* generate alpha electron string */
		str_strfind1(astr1, ci_aelec, ci_orbs, astr2);
		
		/* test docc restrictions */
		axdocc = str_enfdocc(astr2, ci_aelec, ndocc, nactv);
		if (axdocc > xlvl) {
			for (j = 0; j < ci_aelec; j++) {
				astr1[j] = astr2[j];
			}
			continue;
		}
		
		/* test active orbital restrictions */
		axactv = str_enfactv(astr2, ci_aelec, ndocc, nactv);
		if (axactv > xlvl) {
			for (j = 0; j < ci_aelec; j++) {
				astr1[j] = astr2[j];
			}
			continue;
		}
		
		/* if here, |p, 1> is valid (p = i) */
		//fprintf(strfileptr, " %14d\n", i);
                pptr->index = i;
                pptr->xdocc = axdocc;
                pptr->xactv = axactv;
                pptr->next = malloc(sizeof(struct validstr));
                pptr->next->next = NULL;
                pptr = pptr->next;
                
                *astr_len = *astr_len + 1;
		
		for (j = 0; j < ci_belec; j++) {
			bstr1[j] = bstr_hf[j];
		}
		bindx = 1;
		
		/* now loop over valid beta strings */
		qptr = qindxlist;
		while (qptr->next != NULL) {
			
			/* generate orbital string */
			str_strfind2(bstr1, bindx, ci_belec, ci_orbs, qptr->index,
				     bstr2);
			bindx = qptr->index;
			for (j = 0; j < ci_belec; j++) {
				bstr1[j] = bstr2[j];
			}
			
			/* test docc restrictions */
			if ((axdocc + qptr->xdocc) > xlvl) {
				for (j = 0; j < ci_belec; j++) {
					bstr1[j] = bstr2[j];
				}
				qptr = qptr->next;
				continue;
			}
			
			/* test active orbital restrictions */
			if ((axactv + qptr->xactv) > xlvl) {
				for (j = 0; j < ci_belec; j++) {
					bstr1[j] = bstr2[j];
				}
				qptr = qptr->next;
				continue;
			}
			
			/* test together */
			if (((axactv + qptr->xactv) + (axdocc + qptr->xdocc))
			    > xlvl) {
				for (j = 0; j < ci_belec; j++) {
					bstr1[j] = bstr2[j];
				}
				qptr = qptr->next;
				continue;
			}
			
			/* if here, write determinant */
			//fprintf(detfileptr, " %14d %14d\n", i, qptr->index);
                        dptr->pindx = i;
                        dptr->qindx = qptr->index;
                        dptr->next = malloc(sizeof(struct validdet));
                        dptr->next->next = NULL;
                        dptr = dptr->next;
                        
                        *dtrm_len = *dtrm_len + 1;
			
			for (j = 0; j < ci_belec; j++) {
				bstr1[j] = bstr2[j];
			}
			qptr = qptr->next;
		}
		
		for (j = 0; j < ci_aelec; j++) {
			astr1[j] = astr2[j];
		}
	}
	
	fprintf(stdout, "Deallocating electron arrays.\n");
	free(astr1);
	free(astr2);
	free(bstr1);
	free(bstr2);
	free(bstr_hf);
	free(astr_hf);
	
	/* free linked list */
	qptr = qindxlist;
	fprintf(stdout, "Deallocating linked list.\n");
	while (qptr->next != NULL) {
		tmp = qptr;
		qptr = qptr->next;
		
		free(tmp);
	}
	
	fclose(detfileptr);
	fclose(strfileptr);
	return err;
}
Esempio n. 3
0
/**
 * Principal function of the Genetic Algorithm
 * \fn shooter_repartition genetic algorithm heuristic for selection of towers
**/
void shooter_repartition(const char * input_file_name, const float mutation_prob, const int population_size, 
						 const int nb_children, const int nb_iteration, const int dist, float taux_var, bool sim)
{
	vector<tower>* towers = new vector<tower>();
	int k, n;
	tower_parse(input_file_name, *towers, k, n);
	srand((unsigned int) time(NULL));
	if (!is_easy_solution(k, n)) {
		vector<vector<tower>*>* population = generate_initial_pop(towers, k, dist, taux_var);
		sort_population(population);
		vector<vector<tower>*>* children;

		// population growth until reaching population_size
		while ((int) population->size() < population_size) { 
			children = reproduction_iteration(nb_children, mutation_prob, population, towers, dist, taux_var);
			sort_population(children);
			for (int i = 0; i < (int) children->size(); i++) {
				if ((int) population->size() < population_size) { //do not oversize the population_size  && !find_indiv(population, (*children)[i])
					population->push_back((*children)[i]);
				}
				else {
					break;
				}
			}
		}
		// reordering population
		sort_population(population);

		// iteration of genetic algorithm
		for (int j = 0; j < nb_iteration; j++) { 
			children = reproduction_iteration(nb_children, mutation_prob, population, towers, dist, taux_var);
			for (int i = 0; i < (int) children->size(); i++) {
				child_insertion((*children)[i], population);
			}
		}

		// printing the results
		for (int i = 0; i < 10 ; i++) { 
			cout << i+1 << " : ";
			print_indiv((*population)[i]);
		}

		if(sim)
			simulate_day(population->front(), towers, dist, taux_var);

		for (vector<vector<tower>*>::iterator it  = population->begin(); it != population->end(); it++){
			delete *it;
		}
		delete population;
	}
	else { // generate all the permutations and verify which is the best;
		int tmp_eval = 0, best_eval = 0;
		int nb_perm = binomial_coef(n,k);
		int t_size = towers->size();
		int *perm_indexes = (int*) malloc( k * sizeof(int)); //build index tracker to avoid repeating indivs
		vector<tower> *tmp_indiv, *best_indiv;
		tmp_indiv = new vector<tower>();
		best_indiv = new vector<tower>();
		for(int l = 0; l<k; l++){
			perm_indexes[l] = l;
			tmp_indiv->push_back((*towers)[l]);
		}
		// spread var for variance
		spread_indiv_var(tmp_indiv, towers, taux_var);
		*best_indiv = *tmp_indiv;
		best_eval = check_dist(best_indiv, dist) ? eval_indiv(best_indiv) : 0;
		for (int j = 0; j < nb_perm; j++){
			//build and eval permutation
			for (int i = 0; i < k ; i++){
				tmp_indiv->at(i) = towers->at(perm_indexes[i]);
			}
			spread_indiv_var(tmp_indiv, towers, taux_var);
			if(check_dist(tmp_indiv,dist)) {
				tmp_eval = eval_indiv(tmp_indiv);
				if (tmp_eval > best_eval) {
					best_eval = tmp_eval;
					*best_indiv = *tmp_indiv;
				}
			}
			//update of indexes tracker
			perm_indexes[k-1]++;
			for( int m = k-2; m >= 0; m--){ //go to next permutation
				if (perm_indexes[m+1] > t_size-(k-m-1)){
					perm_indexes[m]++;
					for(int p = m+1; p < k; p++){//correcting overflow
						perm_indexes[p] = perm_indexes[p-1]+1; 
					}
				}
			}
		}
		print_indiv(best_indiv);
		
		if (sim)
			simulate_day(best_indiv, towers, dist, taux_var);

		free(perm_indexes);
		delete best_indiv;
		delete tmp_indiv;

	}

	delete towers;
}