如何确定数组中的所有对象是否在Swift中连接

时间:2019-02-26 06:16:20

标签: arrays swift algorithm graph-theory graph-algorithm

我有一个自定义对象(myArray)的数组(MyObject)。数组中的每个对象都连接到数组中的至少一个其他对象(请参见下面的代码)。 我正在尝试找到一种方法来确定myArray中的所有对象是否都相互连接。

class MyObject {
    var id: Int = 0
    var connectedIds: [Int] = []
}

如果myArray包含5个元素(ABCDEA.id = 0 ,B.id = 1,...),我想确定所有五个是否都以某种方式连接。每个对象都有一个与其连接的对象connectedIds中的id数组(不包含自身)。

例如,这将是有效的:

print(A.connectedIds) // [1]
print(B.connectedIds) // [0, 2]
print(C.connectedIds) // [1, 4]
print(D.connectedIds) // [4]
print(E.connectedIds) // [2, 3]

...但这不会:

print(A.connectedIds) // [1]
print(B.connectedIds) // [0]
print(C.connectedIds) // [3, 4]
print(D.connectedIds) // [2, 4]
print(E.connectedIds) // [2, 3]

以图形方式查看(忽略红色圆圈),没关系:okay image

但这不是:not okay image

2 个答案:

答案 0 :(得分:1)

算法基于以下条件:在两个点之间找到一条路线,另一个用于检查是否可以连接所有点(它们之间有路线):

    // Find route from an object to other object
    func findNewRoute(currentRoute: inout [Int], from: Int, to: Int) {
        currentRoute.append(from)
        let connectedObjects = (objects.filter { $0.id == from }.first!).connectedIds
        for index in connectedObjects {
            if !currentRoute.contains(index) {
                findNewRoute(currentRoute: &currentRoute, from: index, to: to)
            }
        }
    }

    // Check Validation
    func checkValid(group: [MyObject]) -> Bool {
        for object in objects {
            if !(objects.filter {
                element in
                var result:[Int] = []
                findNewRoute(currentRoute: &result, from: object.id, to: element.id)
                return !result.contains(element.id)
            }).isEmpty {
                return false
            }
        }
        return true
    }

答案 1 :(得分:0)

这是connected component的图形问题。

您可以在每个节点上进行深度优先搜索,并获取连接的组件。如果结果中有两个以上的组件,那么是的,所有对象都未连接到所有其他对象。

class MyObject {
  var id: Int = 0
  var connectedIds: [Int] = []
}

func isAlreadyVisited(n: MyObject, cc: inout [[MyObject]]) -> Bool {
  for c in cc {
    c.forEach {
      return ($0.id == n.id)
    }
  }
  return false
}

func connectedComponent(g: [MyObject]) -> [[MyObject]] {
  var cc = [[MyObject]]()
  for n in g {
    if !isAlreadyVisited(n: n, cc: &cc) {
      var c = DFS(n, g) // Use placeHolder for DFS, you can write your own
      cc.append(contentsOf: c)
    }
  }
  return cc
}

var cc = connectedComponent(g: [MyObject(), MyObject()])