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; }
void CStaticStructLearnSEM::CreateNeighborCPDs(CBNet* pBNet, pCPDVector* vNeighborCPDs, EDGEOPVECTOR* vValidMoves, intVector* RevCorrespDel) { CGraph* pGraph = pBNet->GetGraph(); CDAG* pDAG = CDAG::Create(*pGraph); CModelDomain* pMD = pBNet->GetModelDomain(); intVector vDiscrete, vContinuous; intVector vAncestor, vDescent; intVector vMixture, vMix; const CNodeType* nt; CFactor* factor; int i, j, position; vAncestor.assign(m_vAncestor.begin(), m_vAncestor.end()); vDescent.assign(m_vDescent.begin(), m_vDescent.end()); pBNet->FindMixtureNodes(&vMix); for(i=0; i<vMix.size(); i++) { factor = pBNet->GetFactor(vMix[i]); j = static_cast<CMixtureGaussianCPD*>(factor) -> GetNumberOfMixtureNode(); vMixture.push_back(j); } for(i=0; i<m_nNodes; i++) { nt = pMD->GetVariableType(i); if( nt->IsDiscrete() ) { vDiscrete.push_back(i); } else vContinuous.push_back(i); } vValidMoves->clear(); vNeighborCPDs->clear(); RevCorrespDel->clear(); pDAG->GetAllValidMove(vValidMoves, &vMixture.front(), vMixture.size(), m_nMaxFanIn, &vDiscrete, &vContinuous, &vDescent, &vAncestor ); int nMoves = vValidMoves->size(); intVector domain; EDGEOP curMove; int start, end; for(i=0; i<nMoves; i++) { domain.clear(); curMove = (*vValidMoves)[i]; switch (curMove.DAGChangeType) { case DAG_DEL : start = curMove.originalEdge.startNode; end = curMove.originalEdge.endNode; factor = pBNet->GetFactor(end); factor->GetDomain(&domain); position = std::find(domain.begin(), domain.end(), start) - domain.begin(); domain.erase(domain.begin()+position); vNeighborCPDs->push_back(CreateRandomCPD(domain.size(), &domain.front(), pBNet)); break; case DAG_ADD : start = curMove.originalEdge.startNode; end = curMove.originalEdge.endNode; factor = pBNet->GetFactor(end); factor->GetDomain(&domain); domain.insert(domain.begin(), start); vNeighborCPDs->push_back(CreateRandomCPD(domain.size(), &domain.front(), pBNet)); break; case DAG_REV : end = curMove.originalEdge.startNode; start = curMove.originalEdge.endNode; factor = pBNet->GetFactor(end); factor->GetDomain(&domain); domain.insert(domain.begin(), start); vNeighborCPDs->push_back(CreateRandomCPD(domain.size(), &domain.front(), pBNet)); break; } } RevCorrespDel->assign(nMoves, -1); EDGEOP pre_move; for(i=0; i<nMoves; i++) { curMove = (*vValidMoves)[i]; if(curMove.DAGChangeType == DAG_REV) { start = curMove.originalEdge.startNode; end = curMove.originalEdge.endNode; for(j=0; j<nMoves; j++) { pre_move = (*vValidMoves)[j]; if( (start == pre_move.originalEdge.startNode) && (end == pre_move.originalEdge.endNode) && (pre_move.DAGChangeType == DAG_DEL) ) { (*RevCorrespDel)[i] = j; break; } } } } }