Skip to content

Commit 5c09860

Browse files
committed
Integrated all code for Set Cover algorithm.
Merge branch 'set-cover'
2 parents 056795e + e963e97 commit 5c09860

File tree

7 files changed

+170
-0
lines changed

7 files changed

+170
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Set Cover (Unweighted)
2+
3+
A cover
4+
5+
If you have a set (also called the universe in the mathematical descriptions of the problem)
6+
7+
## The algorithm
8+
9+
## See also
10+
11+
[Set cover problem on Wikipedia](https://en.wikipedia.org/wiki/Set_cover_problem)
12+
13+
*Written for Swift Algorithm Club by [Michael C. Rael](https://github.com/mrael2)*
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
let universe1 = Set(1...7)
2+
let array1 = randomArrayOfSets(covering: universe1)
3+
let cover1 = universe1.cover(from: array1)
4+
5+
let universe2 = Set(1...10)
6+
let array2: Array<Set<Int>> = [[1,2,3,4,5,6,7], [8,9]]
7+
let cover2 = universe2.cover(from: array2)
8+
9+
let universe3 = Set(["tall", "heavy"])
10+
let array3: Array<Set<String>> = [["tall", "light"], ["short", "heavy"], ["tall", "heavy", "young"]]
11+
let cover3 = universe3.cover(from: array3)
12+
13+
let universe4 = Set(["tall", "heavy", "green"])
14+
let cover4 = universe4.cover(from: array3)
15+
16+
let universe5: Set<Int> = [16, 32, 64]
17+
let array5: Array<Set<Int>> = [[16,17,18], [16,32,128], [1,2,3], [32,64,128]]
18+
let cover5 = universe5.cover(from: array5)
19+
20+
let universe6: Set<Int> = [24, 89, 132, 90, 22]
21+
let array6 = randomArrayOfSets(covering: universe6)
22+
let cover6 = universe6.cover(from: array6)
23+
24+
let universe7: Set<String> = ["fast", "cheap", "good"]
25+
let array7 = randomArrayOfSets(covering: universe7, minArraySizeFactor: 20.0, maxSetSizeFactor: 0.7)
26+
let cover7 = universe7.cover(from: array7)
27+
28+
let emptySet = Set<Int>()
29+
let coverTest1 = emptySet.cover(from: array1)
30+
let coverTest2 = universe1.cover(from: Array<Set<Int>>())
31+
let coverTest3 = emptySet.cover(from: Array<Set<Int>>())
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import Foundation
2+
3+
public func randomArrayOfSets<T>(covering universe: Set<T>,
4+
minArraySizeFactor: Double = 0.8,
5+
maxSetSizeFactor: Double = 0.6) -> Array<Set<T>> {
6+
var result = [Set<T>]()
7+
var ongoingUnion = Set<T>()
8+
9+
let minArraySize = Int(Double(universe.count) * minArraySizeFactor)
10+
var maxSetSize = Int(Double(universe.count) * maxSetSizeFactor)
11+
if maxSetSize > universe.count {
12+
maxSetSize = universe.count
13+
}
14+
15+
while true {
16+
var generatedSet = Set<T>()
17+
let targetSetSize = Int(arc4random_uniform(UInt32(maxSetSize)) + 1)
18+
19+
while true {
20+
let randomUniverseIndex = Int(arc4random_uniform(UInt32(universe.count)))
21+
for (setIndex, value) in universe.enumerate() {
22+
if setIndex == randomUniverseIndex {
23+
generatedSet.insert(value)
24+
break
25+
}
26+
}
27+
28+
if generatedSet.count == targetSetSize {
29+
result.append(generatedSet)
30+
ongoingUnion = ongoingUnion.union(generatedSet)
31+
break
32+
}
33+
}
34+
35+
if result.count >= minArraySize {
36+
if ongoingUnion == universe {
37+
break
38+
}
39+
}
40+
}
41+
42+
return result
43+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
public extension Set {
2+
func cover(from array: Array<Set<Element>>) -> Array<Set<Element>>? {
3+
var result: [Set<Element>]? = [Set<Element>]()
4+
var remainingSet = self
5+
6+
func largestIntersectingSet() -> Set<Element>? {
7+
var largestIntersectionLength = 0
8+
var largestSet: Set<Element>?
9+
10+
for set in array {
11+
let intersectionLength = remainingSet.intersect(set).count
12+
if intersectionLength > largestIntersectionLength {
13+
largestIntersectionLength = intersectionLength
14+
largestSet = set
15+
}
16+
}
17+
18+
return largestSet
19+
}
20+
21+
while remainingSet.count != 0 {
22+
guard let largestSet = largestIntersectingSet() else { break }
23+
result!.append(largestSet)
24+
remainingSet = remainingSet.subtract(largestSet)
25+
}
26+
27+
if remainingSet.count != 0 || self.count == 0 {
28+
result = nil
29+
}
30+
31+
return result
32+
}
33+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='5.0' target-platform='osx'>
3+
<timeline fileName='timeline.xctimeline'/>
4+
</playground>

Set Cover (Unweighted)/SetCover.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
extension Set {
2+
func cover(from array: Array<Set<Element>>) -> Array<Set<Element>>? {
3+
var result: [Set<Element>]? = [Set<Element>]()
4+
var remainingSet = self
5+
6+
func largestIntersectingSet() -> Set<Element>? {
7+
var largestIntersectionLength = 0
8+
var largestSet: Set<Element>?
9+
10+
for set in array {
11+
let intersectionLength = remainingSet.intersect(set).count
12+
if intersectionLength > largestIntersectionLength {
13+
largestIntersectionLength = intersectionLength
14+
largestSet = set
15+
}
16+
}
17+
18+
return largestSet
19+
}
20+
21+
while remainingSet.count != 0 {
22+
guard let largestSet = largestIntersectingSet() else { break }
23+
result!.append(largestSet)
24+
remainingSet = remainingSet.subtract(largestSet)
25+
}
26+
27+
if remainingSet.count != 0 || self.count == 0 {
28+
result = nil
29+
}
30+
31+
return result
32+
}
33+
}

swift-algorithm-club.xcworkspace/contents.xcworkspacedata

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)