union-find

- implement quick find
- implement quick union
- implement quick union with optimization
This commit is contained in:
Raffaele Mignone 2019-03-23 10:09:09 +01:00
parent 2abd5aaa1d
commit 96185eed8e
Signed by: norangebit
GPG Key ID: F5255658CB220573
9 changed files with 450 additions and 0 deletions

View File

@ -0,0 +1,46 @@
/*
* MIT License
*
* Copyright (c) 2019 norangebit
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, tryMerge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package it.norangeb.algorithms.datastructures.unionfind
class QuickFind(private val capacity: Int) : UnionFind {
private val ids = IntArray(capacity) { it }
override fun find(element: Int): Int {
return ids[element]
}
override fun union(first: Int, second: Int) {
val firstId = find(first)
val secondId = find(second)
if (firstId == secondId)
return
for (i in 0 until capacity)
if (ids[i] == firstId)
ids[i] = secondId
}
}

View File

@ -0,0 +1,48 @@
/*
* MIT License
*
* Copyright (c) 2019 norangebit
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, tryMerge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package it.norangeb.algorithms.datastructures.unionfind
class QuickUnion(capacity: Int) : UnionFind {
private val ids = IntArray(capacity) { it }
override fun find(element: Int): Int {
var i = element
while (i != ids[i])
i = ids[i]
return i
}
override fun union(first: Int, second: Int) {
val firstId = find(first)
val secondId = find(second)
if (firstId == secondId)
return
ids[firstId] = secondId
}
}

View File

@ -0,0 +1,50 @@
/*
* MIT License
*
* Copyright (c) 2019 norangebit
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package it.norangeb.algorithms.datastructures.unionfind
class QuickUnionCompressionPath(capacity: Int) : UnionFind {
private val ids = IntArray(capacity) { it }
override fun find(element: Int): Int {
var i = element
while (i != ids[i]) {
ids[i] = ids[ids[i]]
i = ids[i]
}
return i
}
override fun union(first: Int, second: Int) {
val firstId = find(first)
val secondId = find(second)
if (firstId == secondId)
return
ids[firstId] = secondId
}
}

View File

@ -0,0 +1,58 @@
/*
* MIT License
*
* Copyright (c) 2019 norangebit
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package it.norangeb.algorithms.datastructures.unionfind
class QuickUnionWithSize(capacity: Int) : UnionFind {
private val ids = IntArray(capacity) { it }
private val size = IntArray(capacity) { 0 }
override fun find(element: Int): Int {
var i = element
while (i != ids[i])
i = ids[i]
return i
}
override fun union(first: Int, second: Int) {
val firstId = find(first)
val secondId = find(second)
if (firstId == secondId)
return
when {
size[first] < size[second] -> {
ids[firstId] = secondId
size[secondId] += size[firstId]
}
else -> {
ids[secondId] = firstId
size[firstId] += size[secondId]
}
}
}
}

View File

@ -0,0 +1,32 @@
/*
* MIT License
*
* Copyright (c) 2019 norangebit
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, tryMerge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package it.norangeb.algorithms.datastructures.unionfind
interface UnionFind {
fun find(element: Int): Int
fun union(first: Int, second: Int)
fun connected(first: Int, second: Int): Boolean = find(first) == find(second)
}

View File

@ -0,0 +1,54 @@
/*
* MIT License
*
* Copyright (c) 2019 norangebit
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, tryMerge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package it.norangeb.algorithms.datastructures.unionfind
import org.amshove.kluent.`should be equal to`
import org.junit.Before
import org.junit.jupiter.api.Test
class QuickFindTest {
private var unionFind = QuickFind(10)
@Before
fun init() {
unionFind = QuickFind(10)
}
@Test
fun testUnion() {
unionFind.connected(1, 2) `should be equal to` false
unionFind.union(1, 2)
unionFind.connected(1, 2) `should be equal to` true
}
@Test
fun testTransitiveUnion() {
unionFind.connected(1, 3) `should be equal to` false
unionFind.union(1, 2)
unionFind.union(2, 3)
unionFind.connected(1, 3) `should be equal to` true
}
}

View File

@ -0,0 +1,54 @@
/*
* MIT License
*
* Copyright (c) 2019 norangebit
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package it.norangeb.algorithms.datastructures.unionfind
import org.amshove.kluent.`should be equal to`
import org.junit.Before
import org.junit.jupiter.api.Test
class QuickUnionCompressionPathTest {
private var unionFind = QuickUnion(10)
@Before
fun init() {
unionFind = QuickUnion(10)
}
@Test
fun testUnion() {
unionFind.connected(1, 2) `should be equal to` false
unionFind.union(1, 2)
unionFind.connected(1, 2) `should be equal to` true
}
@Test
fun testTransitiveUnion() {
unionFind.connected(1, 3) `should be equal to` false
unionFind.union(1, 2)
unionFind.union(2, 3)
unionFind.connected(1, 3) `should be equal to` true
}
}

View File

@ -0,0 +1,54 @@
/*
* MIT License
*
* Copyright (c) 2019 norangebit
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, tryMerge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package it.norangeb.algorithms.datastructures.unionfind
import org.amshove.kluent.`should be equal to`
import org.junit.Before
import org.junit.jupiter.api.Test
class QuickUnionTest {
private var unionFind = QuickUnion(10)
@Before
fun init() {
unionFind = QuickUnion(10)
}
@Test
fun testUnion() {
unionFind.connected(1, 2) `should be equal to` false
unionFind.union(1, 2)
unionFind.connected(1, 2) `should be equal to` true
}
@Test
fun testTransitiveUnion() {
unionFind.connected(1, 3) `should be equal to` false
unionFind.union(1, 2)
unionFind.union(2, 3)
unionFind.connected(1, 3) `should be equal to` true
}
}

View File

@ -0,0 +1,54 @@
/*
* MIT License
*
* Copyright (c) 2019 norangebit
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package it.norangeb.algorithms.datastructures.unionfind
import org.amshove.kluent.`should be equal to`
import org.junit.Before
import org.junit.jupiter.api.Test
class QuickUnionWithSizeTest {
private var unionFind = QuickUnionWithSize(10)
@Before
fun init() {
unionFind = QuickUnionWithSize(10)
}
@Test
fun testUnion() {
unionFind.connected(1, 2) `should be equal to` false
unionFind.union(1, 2)
unionFind.connected(1, 2) `should be equal to` true
}
@Test
fun testTransitiveUnion() {
unionFind.connected(1, 3) `should be equal to` false
unionFind.union(1, 2)
unionFind.union(2, 3)
unionFind.connected(1, 3) `should be equal to` true
}
}