使用golang在图表中查找Cliques

时间:2015-10-06 06:17:56

标签: algorithm graph go

我正在尝试编写一个能够在图表中找到所有Cliques (complete subgraphs)的算法。每个输入顶点必须只在一个结果Clique中。该算法必须具有O(N^2)时间复杂度。结果中的每个集团必须尽可能大。

package main

import (
    "fmt"
)

type Vertex struct {
    Value int
}

type CompleteSubGraph struct {
    vertecies []Vertex
}

func areConnected(vertex1, vertex2 Vertex) bool {
    // 2 verteces are connected if their value sum is even
    return (vertex1.Value+vertex2.Value)%2 == 0
}

func (vertex1 Vertex) getConnectedVertices(vertices []Vertex, maxVertices int) (verticesConnectedWithVertex1 []Vertex) {
    for _, vertex2 := range vertices {
        if areConnected(vertex1, vertex2) {
            verticesConnectedWithVertex1 = append(verticesConnectedWithVertex1, vertex2)
        }
        if len(verticesConnectedWithVertex1) >= maxVertices {
            break
        }
    }
    return
}

func findAllCompleteSubGraphs(
    vertices []Vertex,
    maximumNumberOfVerticesForSubGraph int,
) (allCompleteSubgraphs []*CompleteSubGraph) {
    /*
       every vertex from input vertices
       must be only in one CompleteSubGraph

       the Algorithm must work not slower than O(N^2)
       where N is len(vertices)

       each vertex from input vertices must be only in one
       resulting CompleteSubGraph

       each CompleteSubGraph must be as big as possible
    */
    for _, vertex1 := range vertices {
        connectedToVertex1 := vertex1.getConnectedVertices(vertices,
            maximumNumberOfVerticesForSubGraph)
        fmt.Println("vertex", vertex1)
        fmt.Println("is connected to", connectedToVertex1)
    }
    return
}

func main() {
    vertices := []Vertex{
        Vertex{Value: 1}, Vertex{Value: 2}, Vertex{Value: 3},
        Vertex{Value: 4}, Vertex{Value: 5}, Vertex{Value: 6},
        Vertex{Value: 7}, Vertex{Value: 8}, Vertex{Value: 9},
        Vertex{Value: 10}, Vertex{Value: 11}, Vertex{Value: 12},
    }
    fmt.Println("result", findAllCompleteSubGraphs(vertices, 3))
}

我正在检查是否有2个椎体使用areConnected功能通过边缘连接。这很简单,但在现实生活中会更复杂。

我必须使用现在定义的func (vertex1 Vertex) getConnectedVertices。 我坚持循环

        for _, vertex1 := range vertices {
            connectedToVertex1 := vertex1.getConnectedVertices(vertices,
                maximumNumberOfVerticesForSubGraph)
            fmt.Println("vertex", vertex1)
            fmt.Println("is connected to", connectedToVertex1)
        }

很难想象如何完成算法。会批评任何建议。

Playground

更新

我想解决的原始问题: 查找通过某些特征相互匹配的人群。当AreConnected喜欢person1person2喜欢person2时,person1为真。任务是按人员列表创建最大规模的人员组。人们相信大团体比小团体更好。

1 个答案:

答案 0 :(得分:1)

O(n ^ 2)没有足够的时间来枚举图中所有可能的派系,即使我们(令人难以置信地乐观地)假设每个集团有O(1)处理时间。考虑由n / 3个不相交的三角形组成的n顶点图 - 即n / 3组3个顶点,每个顶点与其组中的其他2个顶点具有边缘,并且没有其他顶点。请注意,您可以从每个n / 3三角形中独立选择一个顶点来获得一个独立的集合(一组n / 3个顶点,其中没有两个顶点通过边连接)。现在反转该图中的所有边:这给出了一个图,其中相同的顶点选择现在给出了一个大小为n / 3的团。这个大小有3 ^(n / 3)个派系,所有派系都是最大的(不能添加任何顶点并保持派系)。 3 ^(n / 3) 大于n ^ 2,所以你不能希望在O(n ^ 2)时间内列出所有这些派系。