예제 #1
0
Potential* doBNLinearVariableElimination(int nxq, int* xq, int nxe, int* xe, Potential** findings, BayesNet* bayesnet, int* elmorder, Graph* moral) {

	Variable* first = NULL;		// Primeira variável a ser eliminada do potencial

	VertexNode* current = NULL;		// Variável auxiliar para percorrer o Moral Graph

	Potential* result = NULL;		// Potencial resultante da sequencia de operações
	Potential* potential = NULL;	// Variável potencial auxiliar

	Elimination** eliminations = NULL;	// Array com operções de eliminações

	int varelmorder[bnsize(bayesnet)];	// Mapa o id da variável para a ordem de eliminação
	int used[bnsize(bayesnet)];			// Vetor de flag para indicar se um potencial foi utilizado

	SingleLinkedListNode* sllcurrent;

	int i,j,id;
	int nvars, ct_used;

	// Número de variáveis
	nvars = graphsize(moral);

	// Aloca o espaço necessário para o array de operações
	eliminations = malloc(nvars*sizeof(Elimination*));

	for (i=0;i<nvars;i++) {
		// Inicializa o mapa
		varelmorder[elmorder[i]] = i;

		// Inicializa a flag
		used[elmorder[i]] = 0;

		// Monta as eliminações e popula varelmorder
		eliminations[i] = (Elimination*) buildElimination(i,bayesnet->variables[elmorder[i]],1);
	}

	// Tomando Xq, se não NULL, marca as operações que não devem ser marginalizadas
	if (xq!=NULL) { // Apenas por segurança
		for (i=0;i<nxq;i++) eliminations[varelmorder[xq[i]]]->marginalize = 0;
	}

	for (i=0, ct_used=0;i<nvars && ct_used<nvars;i++) {

		// Atribui os potenciais da operação de eliminação
		// 1. Verifica o nó da variável "da vez"
		if (!used[elmorder[i]]) {
			id = elmorder[i];
			if (findings && findings[id]) {
				// Marginaliza a distribuição de probabilidade se necessário
				potential =(bayesnet->potentials[id]->nvars>1)?marginalizeNotRequired(moral,bayesnet->potentials[id]):NULL;
				// Produto do finding pela distribuição de probabilidade
				sllappend(&eliminations[i]->potentials,multPotentials((potential?potential:bayesnet->potentials[id]),findings[id]));
				// Libera o espaço alocado (se necessário)
				if (potential) destroyPotential(&potential);
			} else {
				sllappend(&eliminations[i]->potentials,bayesnet->potentials[id]);
			}
			used[id] = 1;
			ct_used++;
		}

		// 2. Verifica os filhos da variável "da vez"
		current = getVertexChildren(getVertexById(&bayesnet->graph,elmorder[i]))->first;
		while (current!=NULL) {
			if (getVertexById(&moral,current->vertex->id) && !used[current->vertex->id]) {
				id = current->vertex->id;
				if (findings && findings[id]) {
					// Marginaliza a distribuição de probabilidade se necessário
					potential =(bayesnet->potentials[id]->nvars>1)?marginalizeNotRequired(moral,bayesnet->potentials[id]):NULL;
					// Produto do finding pela distribuição de probabilidade
					sllappend(&eliminations[i]->potentials,multPotentials((potential?potential:bayesnet->potentials[id]),findings[id]));
					// Libera o espaço alocado (se necessário)
					if (potential) destroyPotential(&potential);
				} else {
					sllappend(&eliminations[i]->potentials,bayesnet->potentials[id]);
				}
				used[id] = 1;
				ct_used++;
			}
			current = current->next;
		}
	}

	// Executa linearmente a eliminação de variáveis
	for (i=0;i<nvars;i++) {

		// Executa a eliminação
		executeElimination(&eliminations[i]);

		// Adiciona o resultado a uma operação futura
		if (i<(nvars-1)) {
			// Identifica em cada potencial a primeira variável a ser eliminada
			first = NULL;
			potential = eliminations[i]->result;
			for (j=0;j<potential->nvars;j++) {
				if (varelmorder[potential->vars[j]->id]>i) {
					if (first==NULL || varelmorder[potential->vars[j]->id] < varelmorder[first->id]) first = potential->vars[j];
				}
			}
			// Adiciona o potential à operação de eliminação correspondente à próxima variável a ser eliminada
			if (first!=NULL) sllappend(&eliminations[varelmorder[first->id]]->potentials,potential);
		}
	}

	// Copia o resultado da última eliminação
	result = buildPotential(-1,eliminations[(nvars-1)]->result->nvars,eliminations[(nvars-1)]->result->vars,eliminations[(nvars-1)]->result->values);

	// Normaliza o resultado final se necessário
	if (result!=NULL) normalize(result->nvalues,&result->values);

	// Desaloca a memória alocada para esta iteração preservando as demais estruturas

	// Elimina as operações executadas
	for (i=0;i<nvars;i++) destroyElimination(&eliminations[i]);
	free(eliminations);
	eliminations = NULL;

	return result;
}
예제 #2
0
// Método que constroi a árvore de eliminação de threads
ThreadTree* buildBNThreadTree(int nxq, int* xq, int nxe, int* xe, Potential** findings,BayesNet* bayesnet, int* elmorder, Graph* moral, Graph* elmtree,MPI_Comm *everyone) {
	
	int msg = -1;
	MPI_Comm t;
	ThreadTree* threadtree = NULL;		// Árvore de Threads
	ThreadVertex* thread = NULL;		// Variável auxiliar que instancia um vértive da árvore de threads

	VertexNode* child;				// Nó de uma lista ligada simples
	VertexNode* current = NULL;		// Variável auxiliar para percorrer o Moral Graph

	Potential* result = NULL;		// Potencial resultante da sequencia de operações
	Potential* potential = NULL;	// Variável potencial auxiliar

	int varelmorder[bnsize(bayesnet)];	// Mapa o id da variável para a ordem de eliminação
	int used[bnsize(bayesnet)];			// Vetor de flag para indicar se um potencial foi utilizado

	Elimination** eliminations = NULL;

	int nvars, ct_used;;
	int i,j,id;;

	// Número de variáveis envolvidas, pode não ser toda a rede
	nvars = graphsize(elmtree);
	
	//MPI_Comm_spawn(char *command, char *argv[], int maxprocs, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *intercomm, int array_of_errcodes[])
	MPI_Comm_spawn("./mpitask",MPI_ARGV_NULL,nvars,MPI_INFO_NULL,0,MPI_COMM_SELF,everyone,MPI_ERRCODES_IGNORE);
	//MPI_Bcast(&msg,1,MPI_INT,MPI_ROOT,t);
	

	// Monta a estrutura que será utilizada para passar dados para as threads
	eliminations = malloc(nvars*sizeof(Elimination*));

	// Constrói a árvore de thread
	threadtree = buildThreadTree();

	// Cria-se as threads vértices
	for (i=0;i<nvars;i++) {

		// Inicializa o mapa
		varelmorder[elmorder[i]] = i;

		// Inicializa a flag
		used[elmorder[i]] = 0;

		// Monta as eliminações e popula varelmorder
		eliminations[i] = (Elimination*) buildElimination(i,bayesnet->variables[elmorder[i]],1);

		// Constrói uma thread da árvore de thread
		thread = buildThreadVertex(taskVariableElimination,(void*)(eliminations));

		// Atribui o vértice à árvore de threads
		addThreadVertex(&threadtree,&thread);
		
	}

	// Adiciona os arcos de dependência
	for (i=0;i<nvars;i++) {
		child = (getVertexChildren(getVertex(&elmtree,i)))->first;
		while (child!=NULL) {
			addTreeArcByIds(&threadtree,i,child->vertex->id);
			child = child->next;
		}
	}

	//---
	
	// Tomando Xq, se não NULL, marca as operações que não devem ser marginalizadas
	if (xq!=NULL) { // Apenas por segurança
		for (i=0;i<nxq;i++) eliminations[varelmorder[xq[i]]]->marginalize = 0;
	}
	
	for (i=0, ct_used=0;i<nvars && ct_used<nvars;i++) {
	
		// Atribui os potenciais da operação de eliminação
		// 1. Verifica o nó da variável "da vez"
		if (!used[elmorder[i]]) {
			id = elmorder[i];
			if (findings && findings[id]) {
				// Marginaliza a distribuição de probabilidade se necessário
				potential =(bayesnet->potentials[id]->nvars>1)?marginalizeNotRequired(moral,bayesnet->potentials[id]):NULL;
				// Produto do finding pela distribuição de probabilidade
				sllappend(&eliminations[i]->potentials,multPotentials((potential?potential:bayesnet->potentials[id]),findings[id]));
				// Libera o espaço alocado (se necessário)
				if (potential) destroyPotential(&potential);
			} else {
				sllappend(&eliminations[i]->potentials,bayesnet->potentials[id]);
			}
			used[id] = 1;
			ct_used++;
		}
	
		// 2. Verifica os filhos da variável "da vez"
		current = getVertexChildren(getVertexById(&bayesnet->graph,elmorder[i]))->first;
		while (current!=NULL) {
			if (getVertexById(&moral,current->vertex->id) && !used[current->vertex->id]) {
				id = current->vertex->id;
				if (findings && findings[id]) {
					// Marginaliza a distribuição de probabilidade se necessário
					potential =(bayesnet->potentials[id]->nvars>1)?marginalizeNotRequired(moral,bayesnet->potentials[id]):NULL;
					// Produto do finding pela distribuição de probabilidade
					sllappend(&eliminations[i]->potentials,multPotentials((potential?potential:bayesnet->potentials[id]),findings[id]));
					// Libera o espaço alocado (se necessário)
					if (potential) destroyPotential(&potential);
				} else {
					sllappend(&eliminations[i]->potentials,bayesnet->potentials[id]);
				}
				used[id] = 1;
				ct_used++;
			}
			current = current->next;
		}
	
		// Fixa o número de potenciais fixos na elimiantion
		eliminations[i]->nconst = slllength(eliminations[i]->potentials);
	}	

	//---

	// Tem que atribuir NULL para liberar a memória pois eu fiz um malloc explicito para ela
	eliminations = NULL;

	return threadtree;
}
예제 #3
0
파일: checks6.c 프로젝트: 3ki5tj/nauty
static boolean
seemsbad(char *s)
/* Check graph string for apparent problem, if so, correct it */
{
        int i,j,k,m,n;
        char *p,x,pq;
	set *gj;
	long ii;
	int r,rr,topbit,nb,lastj;
	graph g[16];

	if (s[0] != ':') return FALSE;  /* not sparse6 */

	n = graphsize(s);
	if (n != 2 && n != 4 && n != 8 && n != 16) return FALSE;
	m = 1;

	stringtograph(s,g,m);
	if (g[n-1] != bit[n-1]) return FALSE;
	if (g[n-2] == 0) return FALSE;

	g[n-1] = 0;
	p = s+2;

	for (i = n-1, nb = 0; i != 0 ; i >>= 1, ++nb) {}
	topbit = 1 << (nb-1);
	k = 6;
	x = 0;

	lastj = 0;
	for (j = 0; j < n; ++j)
	{
	    gj = GRAPHROW(g,j,m);
	    for (i = 0; i <= j; ++i)
	    {
		if (ISELEMENT(gj,i))
		{
		    if (j == lastj)
		    {
		        x <<= 1;
		        if (--k == 0)
		        {
		            p++;
		            k = 6;
		            x = 0;
		        }
		    }
		    else
		    {
			x = (x << 1) | 1;
			if (--k == 0)
			{
		            p++;
			    k = 6;
			    x = 0;
			}
			if (j > lastj+1)
			{
			    for (r = 0, rr = j; r < nb; ++r, rr <<= 1)
			    {
			        if (rr & topbit) x = (x << 1) | 1;
			        else             x <<= 1;
			        if (--k == 0)
			        {
				    p++;
				    k = 6;
				    x = 0;
			        }
			    }
			    x <<= 1;
			    if (--k == 0)
			    {
				p++;
				k = 6;
				x = 0;
			    }
			}
			lastj = j;
		    }
		    for (r = 0, rr = i; r < nb; ++r, rr <<= 1)
		    {
			if (rr & topbit) x = (x << 1) | 1;
			else             x <<= 1;
			if (--k == 0)
			{
			    p++;
			    k = 6;
			    x = 0;
			}
		    }
		}
	    }
	}

        if (k != 6)
        {
            if (k >= nb+1 && lastj == n-2 && n == (1<<nb))
	    {
                *p++ = BIAS6 + ((x << k) | ((1 << (k-1)) - 1));
	    	return TRUE;
	    }
            else
                return FALSE;
        }
}