CGraph* CreateRandomAndSpecificForIDNetGraph(int num_nodes, int num_indep_nodes, int max_size_family) { PNL_CHECK_LEFT_BORDER(num_nodes, 10); PNL_CHECK_RANGES(num_indep_nodes, 1, num_nodes-1); PNL_CHECK_RANGES(max_size_family, 2, num_nodes); int i, j, k; CGraph *pGraph = CGraph::Create(0, NULL, NULL, NULL); PNL_CHECK_IF_MEMORY_ALLOCATED(pGraph); srand((unsigned int)time(NULL)); pGraph->AddNodes(num_nodes); int num_parents; int ind_parent; intVector prev_nodes(0); for (i = num_indep_nodes; i < num_nodes; i++) { prev_nodes.resize(0); for (j = 0; j < i; j++) prev_nodes.push_back(j); num_parents = rand() % (max_size_family - 1); num_parents += 1; num_parents = (num_parents > i) ? i : num_parents; for (j = 0; j < num_parents; j++) { ind_parent = rand() % prev_nodes.size(); pGraph->AddEdge(prev_nodes[ind_parent], i, 1); prev_nodes.erase(prev_nodes.begin() + ind_parent); } } intVector parents(0); intVector childs(0); for (i = 0; i < num_nodes; i++) { if (pGraph->GetNumberOfChildren(i) == 0) { pGraph->GetParents(i, &parents); for (j = 0; j < parents.size(); j++) { pGraph->GetChildren(parents[j], &childs); for (k = 0; k < childs.size(); k++) if ((childs[k] != i) && (pGraph->GetNumberOfChildren(childs[k]) == 0) && (pGraph->GetNumberOfParents(childs[k]) == 1)) { if (i < childs[k]) { pGraph->RemoveEdge(parents[j], childs[k]); pGraph->AddEdge(i, childs[k], 1); } else { pGraph->AddEdge(childs[k], i, 1); } } } } } return pGraph; }
void CBICLearningEngine::Learn() { CEMLearningEngine *pLearn = NULL; float resultBIC = -FLT_MAX; CBNet *pResultBNet = NULL; intVector resultOrder; pEvidencesVector pEv(m_Vector_pEvidences.size(), NULL ); CModelDomain *pMD = m_pGrModel->GetModelDomain(); int nnodes = m_pGrModel->GetNumberOfNodes(); nodeTypeVector varTypes; pMD->GetVariableTypes(&varTypes); intVector varAss( pMD->GetVariableAssociations(), pMD->GetVariableAssociations() + nnodes ); intVector currentAssociation(nnodes); intVector currentObsNodes(nnodes); int i; for( i = 0; i < nnodes; i++ ) { currentObsNodes[i] = i; } CGraph *pGraph = CGraph::Create(nnodes, NULL, NULL, NULL); CBNet *pBNet; int lineSz = int( nnodes * ( nnodes - 1 ) / 2 ); intVecVector connect; intVector indexes(lineSz, 0); int startNode, endNode; int ind; for( ind = 0; ind < lineSz ; ) { if( indexes[ind] == 1 ) { FindNodesByNumber(&startNode, &endNode, nnodes, ind); pGraph->RemoveEdge(startNode, endNode ); indexes[ind] = 0; ind++; } else { FindNodesByNumber(&startNode, &endNode, nnodes, ind); pGraph->AddEdge(startNode, endNode, 1 ); indexes[ind] = 1; ind = 0; connect.clear(); pGraph->GetConnectivityComponents(&connect); if( connect.size() == 1 ) { do { CGraph *pCopyGraph = CGraph::Copy(pGraph); int j; for( j = 0; j < nnodes; j++ ) { currentAssociation[j] = varAss[currentObsNodes[j]]; } pBNet = CBNet::Create(nnodes, varTypes, currentAssociation, pCopyGraph); pBNet->AllocFactors(); for( j = 0; j < nnodes; j++ ) { pBNet->AllocFactor( j ); pBNet->GetFactor(j)->CreateAllNecessaryMatrices(); } int dimOfModel = DimOfModel(pBNet); int k; for( k = 0; k < pEv.size(); k++ ) { valueVector vls; m_Vector_pEvidences[k]->GetRawData(&vls); pEv[k] = CEvidence::Create( pBNet->GetModelDomain(),currentObsNodes, vls ); } pLearn = CEMLearningEngine::Create(pBNet); pLearn->SetData(pEv.size(), &pEv.front()); pLearn->Learn(); int nsteps; const float *score; pLearn->GetCriterionValue(&nsteps, &score); float log_lik = score[nsteps-1]; float BIC = log_lik - 0.5f*float( dimOfModel*log(float(pEv.size())) ); if( BIC >= resultBIC ) { delete pResultBNet; resultBIC = BIC; m_critValue.push_back(BIC); pResultBNet = pBNet; resultOrder.assign( currentObsNodes.begin(), currentObsNodes.end() ); } else { delete pBNet; } for( k = 0; k < pEv.size(); k++ ) { delete pEv[k]; } delete pLearn; }while(std::next_permutation(currentObsNodes.begin(), currentObsNodes.end())); } } } delete pGraph; m_pResultGrModel = pResultBNet; m_resultRenaming.assign(resultOrder.begin(), resultOrder.end()); }