Exemple #1
0
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;
}
Exemple #2
0
CIDNet* CreateRandomIDNet(int num_nodes, int num_indep_nodes,
  int max_size_family, int num_decision_nodes, int max_num_states_chance_nodes,
  int max_num_states_decision_nodes, int min_utility, int max_utility,
  bool is_uniform_start_policy)
{
  PNL_CHECK_RANGES(num_decision_nodes, 1, num_nodes-1);
  PNL_CHECK_LEFT_BORDER(max_num_states_chance_nodes, 1);
  PNL_CHECK_LEFT_BORDER(max_num_states_decision_nodes, 1);
  PNL_CHECK_LEFT_BORDER(max_utility, min_utility);
  
  CGraph* pGraph = 
    CreateRandomAndSpecificForIDNetGraph(num_nodes, num_indep_nodes,
    max_size_family);
  
  if (!pGraph->IsDAG())
  {
    PNL_THROW(CInconsistentType, " the graph should be a DAG ");
  }
  
  if (!pGraph->IsTopologicallySorted())
  {
    PNL_THROW(CInconsistentType, 
      " the graph should be sorted topologically ");
  }
  if (pGraph->NumberOfConnectivityComponents() > 1)
  {
    PNL_THROW(CInconsistentType, " the graph should be linked ");
  }
  
  int i, j, k;
  
  CNodeType *nodeTypes = new CNodeType [num_nodes];
  
  intVector nonValueNodes(0);
  intVector posibleDecisionNodes(0);
  nonValueNodes.resize(0);
  posibleDecisionNodes.resize(0);
  for (i = 0; i < num_nodes; i++)
  {
    if (pGraph->GetNumberOfChildren(i) == 0)
    {
      nodeTypes[i].SetType(1, 1, nsValue);
    }
    else
    {
      nonValueNodes.push_back(i);
      posibleDecisionNodes.push_back(i);
    }
  }
  int ind_decision_node;
  int num_states;
  int index;
  int node;
  intVector neighbors(0);
  neighborTypeVector neigh_types(0);

  num_decision_nodes = (num_decision_nodes > posibleDecisionNodes.size()) ? 
    posibleDecisionNodes.size() : num_decision_nodes;
  for (i = 0; (i < num_decision_nodes) && (posibleDecisionNodes.size()>0); i++)
  {
    ind_decision_node = rand() % posibleDecisionNodes.size();
    node = posibleDecisionNodes[ind_decision_node];
    num_states = GetRandomNumberOfStates(max_num_states_decision_nodes);
    nodeTypes[node].SetType(1, num_states, nsDecision);
    
    index = -1;
    for (j = 0; j < nonValueNodes.size(); j++)
    {
      if (nonValueNodes[j] == node)
      {
        index = j;
        break;
      }
    }
    if (index != -1)
      nonValueNodes.erase(nonValueNodes.begin() + index);
      
    posibleDecisionNodes.erase(posibleDecisionNodes.begin() + 
      ind_decision_node);
    pGraph->GetNeighbors(node, &neighbors, &neigh_types);
    for (j = 0; j < neighbors.size(); j++)
    {
      index = -1;
      for (k = 0; k < posibleDecisionNodes.size(); k++)
      {
        if (neighbors[j] == posibleDecisionNodes[k])
        {
          index = k;
          break;
        }
      }
      if (index != -1)
        posibleDecisionNodes.erase(posibleDecisionNodes.begin() + index);
    }
  }
  for (i = 0; i < nonValueNodes.size(); i++)
  {
    num_states = GetRandomNumberOfStates(max_num_states_chance_nodes);
    nodeTypes[nonValueNodes[i]].SetType(1, num_states, nsChance);
  }
  
  int *nodeAssociation = new int[num_nodes];
  for (i = 0; i < num_nodes; i++)
  {
    nodeAssociation[i] = i;
  }
  
  CIDNet *pIDNet = CIDNet::Create(num_nodes, num_nodes, nodeTypes,
    nodeAssociation, pGraph);
  pGraph = pIDNet->GetGraph();
  CModelDomain* pMD = pIDNet->GetModelDomain();
  
  CFactor **myParams = new CFactor*[num_nodes];
  int *nodeNumbers = new int[num_nodes];
  int **domains = new int*[num_nodes];
  
  intVector parents(0);
  for (i = 0; i < num_nodes; i++)
  {
    nodeNumbers[i] = pGraph->GetNumberOfParents(i) + 1;
    domains[i] = new int[nodeNumbers[i]];
    pGraph->GetParents(i, &parents);
    
    for (j = 0; j < parents.size(); j++)
    {
      domains[i][j] = parents[j];
    }
    domains[i][nodeNumbers[i]-1] = i;
  }
  
  pIDNet->AllocFactors();
  
  for (i = 0; i < num_nodes; i++)
  {
    myParams[i] = CTabularCPD::Create(domains[i], nodeNumbers[i], pMD);
  }
  
  float **data = new float*[num_nodes];
  int size_data;
  int num_states_node;
  int num_blocks;
  intVector size_nodes(0);
  float belief, sum_beliefs;
  
  for (i = 0; i < num_nodes; i++)
  {
    size_data = 1;
    size_nodes.resize(0);
    for (j = 0; j < nodeNumbers[i]; j++)
    {
      size_nodes.push_back(pIDNet->GetNodeType(domains[i][j])->GetNodeSize());
      size_data *= size_nodes[j];
    }
    num_states_node = size_nodes[size_nodes.size() - 1];
    num_blocks = size_data / num_states_node;
    
    data[i] = new float[size_data];
    switch (pIDNet->GetNodeType(i)->GetNodeState())
    {
      case nsChance:
      {
        for (j = 0; j < num_blocks; j++)
        {
          sum_beliefs = 0.0;
          for (k = 0; k < num_states_node - 1; k++)
          {
            belief = GetBelief(1.0f - sum_beliefs);
            data[i][j * num_states_node + k] = belief;
            sum_beliefs += belief;
          }
          belief = 1.0f - sum_beliefs;
          data[i][j * num_states_node + num_states_node - 1] = belief;
        }
        break;
      }
      case nsDecision:
      {
        if (is_uniform_start_policy)
        {
          belief = 1.0f / float(num_states_node);
          for (j = 0; j < num_blocks; j++)
          {
            sum_beliefs = 0.0;
            for (k = 0; k < num_states_node - 1; k++)
            {
              data[i][j * num_states_node + k] = belief;
              sum_beliefs += belief;
            }
            data[i][j * num_states_node + num_states_node - 1] = 
              1.0f - sum_beliefs;
          }
        }
        else
        {
          for (j = 0; j < num_blocks; j++)
          {
            sum_beliefs = 0.0;
            for (k = 0; k < num_states_node - 1; k++)
            {
              belief = GetBelief(1.0f - sum_beliefs);
              data[i][j * num_states_node + k] = belief;
              sum_beliefs += belief;
            }
            belief = 1.0f - sum_beliefs;
            data[i][j * num_states_node + num_states_node - 1] = belief;
          }
        }
        break;
      }
      case nsValue:
      {
        for (j = 0; j < num_blocks; j++)
        {
          data[i][j] = float(GetUtility(min_utility, max_utility));
        }
        break;
      }
    }
  }

  for (i = 0; i < num_nodes; i++)
  {
    myParams[i]->AllocMatrix(data[i], matTable);
    pIDNet->AttachFactor(myParams[i]);
  }

  delete [] nodeTypes;
  delete [] nodeAssociation;

  return pIDNet;
}
Exemple #3
0
int testRandomFactors()
{
    int ret = TRS_OK;
    
    int nnodes = 0;
    int i;
    while(nnodes <= 0)
    {
        trsiRead( &nnodes, "5", "Number of nodes in Model" );
    }
    //create node types
    int seed1 = pnlTestRandSeed();
    //create string to display the value
    char *value = new char[20];
#if 0
    value = _itoa(seed1, value, 10);
#else
    sprintf( value, "%d", seed1 );
#endif
    trsiRead(&seed1, value, "Seed for srand to define NodeTypes etc.");
    delete []value;
    trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "seed for rand = %d\n", seed1);
    //create 2 node types and model domain for them
    nodeTypeVector modelNodeType;
    modelNodeType.resize(2);
    modelNodeType[0] = CNodeType( 1, 4 );
    modelNodeType[1] = CNodeType( 1, 3 );
    intVector NodeAssociat;
    NodeAssociat.assign(nnodes, 0);
    for( i = 0; i < nnodes; i++ )
    {
        float rand = pnlRand( 0.0f, 1.0f );
        if( rand < 0.5f )
        {
            NodeAssociat[i] = 1;
        }
    }
    CModelDomain* pMDDiscr = CModelDomain::Create( modelNodeType,
        NodeAssociat );
    //create random graph - number of nodes for every node is rand too
    int lowBorder = nnodes - 1;
    int upperBorder = int((nnodes * (nnodes - 1))/2);
    int numEdges = pnlRand( lowBorder, upperBorder );
mark: 
    CGraph* pGraph = tCreateRandomDAG( nnodes, numEdges, 1 );
    if ( pGraph->NumberOfConnectivityComponents() != 1 )
    {
        delete pGraph;
        goto mark;
    }
    CBNet* pDiscrBNet = CBNet::CreateWithRandomMatrices( pGraph, pMDDiscr );
    //start jtree inference just for checking 
    //the model is valid for inference and all operations can be made
    CEvidence* pDiscrEmptyEvid = CEvidence::Create( pMDDiscr, 0, NULL, valueVector() );
    CJtreeInfEngine* pDiscrInf = CJtreeInfEngine::Create( pDiscrBNet );
    pDiscrInf->EnterEvidence( pDiscrEmptyEvid );
    const CPotential* pot = NULL;
    for( i = 0; i < nnodes; i++ )
    {
        intVector domain;
        pDiscrBNet->GetFactor(i)->GetDomain( &domain );
        pDiscrInf->MarginalNodes( &domain.front(), domain.size() );
        pot = pDiscrInf->GetQueryJPD();
    }
    //make copy of Graph for using with other models
    pGraph = CGraph::Copy( pDiscrBNet->GetGraph() );
    delete pDiscrInf;
    delete pDiscrBNet;
    delete pDiscrEmptyEvid;
    delete pMDDiscr;  

    //create gaussian model domain
    modelNodeType[0] = CNodeType( 0, 4 );
    modelNodeType[1] = CNodeType( 0, 2 );
    CModelDomain* pMDCont = CModelDomain::Create( modelNodeType,
        NodeAssociat );
    CBNet* pContBNet = CBNet::CreateWithRandomMatrices( pGraph, pMDCont );
    CEvidence* pContEmptyEvid = CEvidence::Create( pMDCont, 0, NULL, valueVector() );
    CNaiveInfEngine* pContInf = CNaiveInfEngine::Create( pContBNet );
    pContInf->EnterEvidence( pContEmptyEvid );
    for( i = 0; i < nnodes; i++ )
    {
        intVector domain;
        pContBNet->GetFactor(i)->GetDomain( &domain );
        pContInf->MarginalNodes( &domain.front(), domain.size() );
        pot = pContInf->GetQueryJPD();
    }

    pGraph = CGraph::Copy(pContBNet->GetGraph());
    delete pContInf;
    delete pContBNet;
    delete pContEmptyEvid;
    delete pMDCont;
    //find the node that haven't any parents 
    //and change its node type for it to create Conditional Gaussian CPD
    int numOfNodeWithoutParents = -1;
    intVector parents;
    parents.reserve(nnodes);
    for( i = 0; i < nnodes; i++ )
    {
        pGraph->GetParents( i, &parents );
        if( parents.size() == 0 )
        {
            numOfNodeWithoutParents = i;
            break;
        }
    }
    //change node type of this node, make it discrete
    CNodeType ntTab = CNodeType( 1,4 );
    modelNodeType.push_back( ntTab );
    NodeAssociat[numOfNodeWithoutParents] = 2;
    //need to change this model domain
    CModelDomain* pMDCondGau = CModelDomain::Create( modelNodeType, NodeAssociat );
    CBNet* pCondGauBNet = CBNet::CreateWithRandomMatrices( pGraph, pMDCondGau );
    //need to create evidence for all gaussian nodes
    intVector obsNodes;
    obsNodes.reserve(nnodes);
    int numGauVals = 0;
    for( i = 0; i < numOfNodeWithoutParents; i++ )
    {
        int GauSize = pMDCondGau->GetVariableType(i)->GetNodeSize();
        numGauVals += GauSize;
        obsNodes.push_back( i );
    }
    for( i = numOfNodeWithoutParents + 1; i < nnodes; i++ )
    {
        int GauSize = pMDCondGau->GetVariableType(i)->GetNodeSize();
        numGauVals += GauSize;
        obsNodes.push_back( i );
    }
    valueVector obsGauVals;
    obsGauVals.resize( numGauVals );
    floatVector obsGauValsFl;
    obsGauValsFl.resize( numGauVals);
    pnlRand( numGauVals, &obsGauValsFl.front(), -3.0f, 3.0f);
    //fill the valueVector
    for( i = 0; i < numGauVals; i++ )
    {
        obsGauVals[i].SetFlt(obsGauValsFl[i]);
    }
    CEvidence* pCondGauEvid = CEvidence::Create( pMDCondGau, obsNodes, obsGauVals );
    CJtreeInfEngine* pCondGauInf = CJtreeInfEngine::Create( pCondGauBNet );
    pCondGauInf->EnterEvidence( pCondGauEvid );
    pCondGauInf->MarginalNodes( &numOfNodeWithoutParents, 1 );
    pot = pCondGauInf->GetQueryJPD();
    pot->Dump();

    delete pCondGauInf;
    delete pCondGauBNet;
    delete pCondGauEvid;
    delete pMDCondGau;

    return trsResult( ret, ret == TRS_OK ? "No errors" : 
    "Bad test on RandomFactors");
}