float CMlStaticStructLearn::ScoreDAG(CDAG* pDAG, floatVector* familyScore) { familyScore->clear(); intVector vFamily; float fscore, score = 0.0f; if (m_ScoreMethod == MarLh) { score = 1.0f; } for(int i=0; i<m_nNodes; i++) { vFamily.clear(); pDAG->GetParents(i, &vFamily); vFamily.push_back(i); fscore = ScoreFamily(vFamily); familyScore->push_back(fscore); if (m_ScoreMethod == MarLh) { score *= fscore; } else { score += fscore; } } return score; }
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; }