Exemplo n.º 1
0
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;
				}
			}
		}
	}
}