find Cliques in a graph using golang

huangapple go评论89阅读模式
英文:

find Cliques in a graph using golang

问题

我正在尝试编写一个算法,用于在图中找到所有的团(完全子图)。每个输入顶点只能属于一个结果团。该算法的时间复杂度必须为O(N^2)。结果中的每个团都应尽可能大。

package main

import (
    "fmt"
)

type Vertex struct {
    Value int
}

type CompleteSubGraph struct {
    vertices []Vertex
}

func areConnected(vertex1, vertex2 Vertex) bool {
    // 如果两个顶点的值之和为偶数,则它们是相连的
    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) {
    /*
       输入顶点中的每个顶点
       只能属于一个完全子图

       算法的时间复杂度不能慢于O(N^2)
       其中N为vertices的长度

       输入顶点中的每个顶点只能属于一个
       结果完全子图

       每个完全子图应尽可能大
    */
    for _, vertex1 := range vertices {
        connectedToVertex1 := vertex1.getConnectedVertices(vertices,
            maximumNumberOfVerticesForSubGraph)
        fmt.Println("顶点", vertex1)
        fmt.Println("与之相连的顶点", 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("结果", findAllCompleteSubGraphs(vertices, 3))
}

我正在使用areConnected函数来检查两个顶点是否通过边相连。这只是一个简单的示例,实际中可能更复杂。

我必须按照现在定义的方式使用func (vertex1 Vertex) getConnectedVertices函数。我在下面的循环中遇到了困难:

for _, vertex1 := range vertices {
    connectedToVertex1 := vertex1.getConnectedVertices(vertices,
        maximumNumberOfVerticesForSubGraph)
    fmt.Println("顶点", vertex1)
    fmt.Println("与之相连的顶点", connectedToVertex1)
}

很难想象如何完成这个算法。我将非常感谢任何建议。

Playground

更新

我试图解决的原始问题是:根据某些特征找到彼此匹配的人群。当person1喜欢person2person2喜欢person1时,areConnected函数返回true。任务是根据人员列表创建尽可能大的人群。人群越大,越好。

英文:

I am trying to write an algorithm which will find all Cliques (complete subgraphs) in a graph. Each input vertex must be only in one resulting Clique. The algorithm must have O(N^2) time complexity. Each clique in the result must be as big as possible.

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))
}

I am checking if 2 vertecies are connected by an edge using areConnected function. It's simple just for example but will be more complicated in real life.

I have to use func (vertex1 Vertex) getConnectedVertices as it is defined now.
I stuck on the cycle

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

Can hardly imagine how to finish the algorithm. Will appriciate any advise.

Playground

Update

The original problem which I am trying to solve:
Find groups of people who fit each other by some characteristics. AreConnected is true when person1 likes person2 and person2 likes person1. The task is to create groups of people with maximum size by a list of people. It is believed that big groups are better than small groups.

答案1

得分: 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)的时间内列出所有这些团。

英文:

O(n^2) isn't enough time to enumerate all possible cliques in a graph, even if we (incredibly optimistically) assume O(1) processing time per clique. Consider an n-vertex graph consisting of n/3 disjoint triangles -- that is, n/3 sets of 3 vertices, with each vertex having edges to the other 2 vertices in its group and to no other vertices. Notice that you can independently choose a single vertex from each of the n/3 triangles to get an independent set (a set of n/3 vertices, no two of which are connected by an edge). Now invert all edges in this graph: this gives a graph in which the same choice of vertices now gives a clique of size n/3. There are 3^(n/3) cliques of this size, all of which are maximal (cannot have any vertices added to them and remain cliques). 3^(n/3) is much larger than n^2, so you cannot hope to even list all these cliques in O(n^2) time.

huangapple
  • 本文由 发表于 2015年10月6日 14:17:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/32962987.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定