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; }
// 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; }
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; } }