【问题标题】:How to obtain all the subgraphs from a graph?如何从一个图中获取所有子图?
【发布时间】:2010-01-01 19:40:13
【问题描述】:

如何以伪代码从图中获取所有固定大小的子图? (蛮力)

尽可能不使用外部库。谢谢!

【问题讨论】:

  • 家庭作业?如果是这样,请使用作业标签。
  • 那将是所有顶点子集的集合和所有边子集的集合的笛卡尔积,对吧?
  • Crisco:你刚刚问了一个关于派系算法的问题。我严重建议你尝试自己做功课,期末期末我们不会在那里
  • 如果是家庭作业,相信我,我不会在这里...谢谢 Pau!
  • 我不认为 Pau 的回答是完全正确的,因为它表明边的数量和顶点的数量是相互独立的。删除一个顶点意味着某些边将不再存在,因此子集的简单笛卡尔积将不会这样做。

标签: algorithm graph brute-force subgraph


【解决方案1】:

或多或少是这样的:

GenerateSubgraphs(Graph G):
    powerV = powerset(G.V)
    powerE = powerset(G.E)
    subgraphs = {}
    foreach V in powerV:
        foreach E in powerE:
            accept = true
            foreach edge in E:
                if edge.u not in V or edge.v not in V:
                    accept = false
            if accept:
                subgraphs.insert((V, E))
    return subgraphs

编辑:修复了“edges.insert”行的缩进

编辑:删除重复的图表

【讨论】:

  • 这没关系,但实际上你不需要构建edges。如果对于给定的组合 (V, E),E 提到了不在 V 中的任何顶点,则可以跳过它。
  • 哇,没错。固定边将在另一次迭代中生成。正在修复它...
【解决方案2】:

由于图只有边和顶点,找到所有可能的顶点子集,并在它们上构造所有可能的边子集。

【讨论】:

    【解决方案3】:

    如果您使用的是 boost 子图,我有一个以下解决方案来迭代所有子图并准备其向量。

    // declare the list types
    vector<SubGraph*> m_vecSubgraphContainer;
    vector<SubGraph*> m_vecBFSOrderedSubgraphs; 
    
    // construct container of subgraph lists in the vector
    m_vecSubgraphContainer.push_back(&gInputGraph);
    
    m_vecBFSOrderedSubgraphs.push_back(&gInputGraph);
    iterateChildrenGraphs(m_vecBFSOrderedSubgraphs);
    
    // iterating the subgraphs
    for(vector<SubGraph*>::iterator itrSubgraph = m_vecSubgraphContainer.begin();
        itrSubgraph != m_vecSubgraphContainer.end();
        ++itrSubgraph)
    {
        // for empty graph add dummy node to that graph
        int iNumVertices = num_vertices(**itrSubgraph);
        if(iNumVertices == 0)
        {
            VertexDescriptor vVertex = m_boostGraphWrapper.addVertex(**itrSubgraph, Enum::InvisibleNode);
            // This dummy node will set the size of cluster
            // set height = 80 nd width = 80;
            int iDummyNodeHeight = 80;
            int iDummyNodeWidth = 80;
            m_boostGraphWrapper.setVertexHeight(vVertex,**itrSubgraph, iDummyNodeHeight);
            m_boostGraphWrapper.setVertexWidth(vVertex, **itrSubgraph, iDummyNodeWidth);
        }
    }
    
    void CircularLayoutGenerator::iterateChildrenGraphs(vector<SubGraph *> &subgraphQueue)
    {
    /*
        we have used queue because it will contains reference of subgraphs.
        adding all the subgraphs in queue to iterate one by one in circular way.
    */
    
    // define local queue which will contains the childrens of main graph
    vector<SubGraph*> SubgraphSequence;
    
    try
    {
        // To iterate input queue which will contain graph reference
        for( vector<SubGraph*>::iterator itrSubgraphQueue = subgraphQueue.begin();
             itrSubgraphQueue != subgraphQueue.end();
             itrSubgraphQueue++)
        {
            // Finding the children upto deep level
            SubGraph::children_iterator itrSubgraph, itrSubgraphEnd;
            for (boost::tie(itrSubgraph, itrSubgraphEnd) = (**itrSubgraphQueue).children();
                 itrSubgraph != itrSubgraphEnd;
                 ++itrSubgraph)
            {
                // Add children in the global queue container
                m_vecSubgraphContainer.push_back(&(*itrSubgraph));
    
                // Add children in the local queue conatainer
                SubgraphSequence.push_back(&(*itrSubgraph));
            }
        }
    }
    
    // To iterarte the local queue again if ant children is present
    if(!SubgraphSequence.empty())
    {
        // Recursive call to iterate children
        iterateChildrenGraphs(SubgraphSequence);
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-16
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多