void CMlStaticStructLearn::CreateResultBNet(CDAG* pDAG) { int i, j, k, ns; int nnodes = m_nNodes; CDAG* iDAG = pDAG->TopologicalCreateDAG(m_vResultRenaming); nodeTypeVector vnt; m_pGrModel->GetNodeTypes(&vnt); intVector na(nnodes); const int* nas = m_pGrModel->GetNodeAssociations(); for(i=0; i<nnodes; i++) na[i] = nas[m_vResultRenaming[i]]; m_pResultBNet = CBNet::Create(nnodes, vnt.size(), &vnt.front(), &na.front(), static_cast<CGraph*>(iDAG)); const CNodeType* nt; int nEv = m_Vector_pEvidences.size(); CEvidence** pEv = new CEvidence*[nEv]; intVector obsnodes(nnodes); for(i=0; i<nnodes; i++) obsnodes[i] = i; valueVector new_data; const Value* val; for(i = 0 ; i < nEv; i++) { for(j=0; j<nnodes; j++) { val = m_Vector_pEvidences[i]->GetValue(m_vResultRenaming[j]); nt = m_pResultBNet->GetNodeType(j); if(nt->IsDiscrete()) { new_data.push_back(*val); } else { ns = nt->GetNodeSize(); for(k=0; k<ns; k++) new_data.push_back(*(val+k)); } } pEv[i] = CEvidence::Create(m_pResultBNet, nnodes, &obsnodes.front(), new_data); new_data.clear(); } vnt.clear(); intVector vFamily; m_pResultBNet->AllocFactors(); for(i=0; i<nnodes; i++) { vFamily.clear(); iDAG->GetParents(i, &vFamily); vFamily.push_back(i); CCPD* iCPD = ComputeFactor(vFamily, m_pResultBNet, pEv); m_pResultBNet->AttachFactor(iCPD); } for(i=0; i<nEv; i++)delete pEv[i]; delete[] pEv; }
void CMlStaticStructLearnHC::LearnInOneStart(CDAG* InitDag, CDAG** LearnedDag, float* LearnedScore) { int i, j, step=0; bool progress = true; CDAG* iDAG = InitDag->Clone(); floatVector FamilyScore; float init_score = ScoreDAG(iDAG, &FamilyScore); int nValidMoves; EDGEOPVECTOR vValidMoves; EDGEOP move; intVector newFamily; intVector vAncestor, vDescent; intVector vDiscrete, vContinuous; int start, end, position; const CNodeType* nt; for(i=0; i<m_nNodes; i++) { nt = m_pGrModel->GetNodeType(i); if( nt->IsDiscrete() ) vDiscrete.push_back(i); else vContinuous.push_back(i); } vAncestor.assign(m_vAncestor.begin(), m_vAncestor.end()); vDescent.assign(m_vDescent.begin(), m_vDescent.end()); while ( step<m_nSteps && progress ) { iDAG->GetAllValidMove(&vValidMoves,&vDiscrete, &vContinuous, &vDescent, &vAncestor); nValidMoves = vValidMoves.size(); float tmp_score, max_score = 0.0f; float tmp_start, max_start = 0.0f; float tmp_end, max_end = 0.0f; int max_index = 0; for(i=0; i<nValidMoves; i++) { newFamily.clear(); move = vValidMoves[i]; switch (move.DAGChangeType) { case DAG_DEL : start = move.originalEdge.startNode; end = move.originalEdge.endNode; iDAG->GetParents(end, &newFamily); newFamily.push_back(end); position = std::find(newFamily.begin(), newFamily.end(), start) - newFamily.begin(); newFamily.erase(newFamily.begin()+position); tmp_score = ScoreFamily(newFamily) - FamilyScore[end]; if(tmp_score > max_score) { max_score = tmp_score; max_index = i; } break; case DAG_ADD : start = move.originalEdge.startNode; end = move.originalEdge.endNode; iDAG->GetParents(end, &newFamily); position = newFamily.size(); for(j=0; j<newFamily.size(); j++) { if(start<newFamily[j]) { position = j; break; } } if(position == int(newFamily.size())) newFamily.push_back(start); else newFamily.insert(newFamily.begin()+position, start); newFamily.push_back(end); if(newFamily.size() > (m_nMaxFanIn+1)) break; tmp_score = ScoreFamily(newFamily) - FamilyScore[end]; if(tmp_score > max_score) { max_score = tmp_score; max_index = i; } break; case DAG_REV : start = move.originalEdge.startNode; end = move.originalEdge.endNode; iDAG->GetParents(start, &newFamily); //add an edge position = newFamily.size(); for(j=0; j<newFamily.size(); j++) { if(end<newFamily[j]) { position = j; break; } } if(position == int(newFamily.size())) newFamily.push_back(end); else newFamily.insert(newFamily.begin()+position, end); newFamily.push_back(start); if(newFamily.size() > (m_nMaxFanIn+1)) break; tmp_score = ScoreFamily(newFamily) - FamilyScore[start]; tmp_start = tmp_score; start = move.originalEdge.startNode; end = move.originalEdge.endNode; iDAG->GetParents(end, &newFamily); newFamily.push_back(end); position = std::find(newFamily.begin(), newFamily.end(), start) - newFamily.begin(); newFamily.erase(newFamily.begin()+position); tmp_score = ScoreFamily(newFamily) - FamilyScore[end]; tmp_end = tmp_score; tmp_score = tmp_start + tmp_end; if(tmp_score > max_score) { max_score = tmp_score; max_start = tmp_start; max_end = tmp_end; max_index = i; } break; } } float score_gate = (float)fabs(m_minProgress * init_score); if(max_score <= score_gate) { vValidMoves.clear(); progress = false; break; } move = vValidMoves[max_index]; start = move.originalEdge.startNode; end = move.originalEdge.endNode; switch (move.DAGChangeType) { case DAG_DEL : if(iDAG->DoMove(start, end, DAG_DEL)) { init_score += max_score; FamilyScore[end] += max_score; } break; case DAG_ADD : if(iDAG->DoMove(start, end, DAG_ADD)) { init_score += max_score; FamilyScore[end] += max_score; } break; case DAG_REV : if(iDAG->DoMove(start, end, DAG_REV)) { init_score += max_score; FamilyScore[start] += max_start; FamilyScore[end] += max_end; } break; } vValidMoves.clear(); step++; } *LearnedScore = this->ScoreDAG(iDAG, &FamilyScore); *LearnedDag = iDAG->Clone(); delete iDAG; }