Skip to content

Commit

Permalink
Improve performance and fix issues with successor lookahead, HROTGene…
Browse files Browse the repository at this point in the history
…rations and HROTExtendedGenerations
  • Loading branch information
jedlimlx committed May 19, 2024
1 parent 968a759 commit ca91e37
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 28 deletions.
17 changes: 11 additions & 6 deletions src/commonMain/kotlin/rules/hrot/HROTExtendedGenerations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -355,25 +355,30 @@ class HROTExtendedGenerations : BaseHROT {
}

override fun transitionFuncWithUnknowns(cells: IntArray, cellState: Int, generation: Int, coordinate: Coordinate): Int {
if (cellState !in activeStates && cellState != 0) return 1 shl (cellState + 1).mod(numStates)

var unknowns = 0
var live = 0
cells.forEachIndexed { index, it ->
if (it == -1) unknowns += (weights?.get(index) ?: 1)
else if (it in activeStates) live += (weights?.get(index) ?: 1)
if (it == -1) unknowns += 1
else if (it in activeStates) live += 1
}

var count = 0
for (i in live..(live+unknowns)) {
if (if (cellState in activeStates) i in survival else i in birth)
if (if (cellState == 0) i in birth else i in survival)
count++
}

var state = 0b00
var state = 0
if (count != 0) {
if (state == 0) state += 0b10
if (cellState == 0) state += 1 shl 1
else state += 1 shl cellState
}
if (count < unknowns + 1) state += 1 shl ((cellState + 1).mod(numStates))
if (count < unknowns + 1) {
if (cellState == 0) state += 1 shl 0
else state += 1 shl ((cellState + 1).mod(numStates))
}

return state
}
Expand Down
18 changes: 13 additions & 5 deletions src/commonMain/kotlin/rules/hrot/HROTGenerations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -360,12 +360,14 @@ class HROTGenerations : BaseHROT {
}

override fun transitionFuncWithUnknowns(cells: IntArray, cellState: Int, generation: Int, coordinate: Coordinate): Int {
if (cellState > 1) return 1 shl (cellState + 1).mod(numStates)

if (weights == null) {
var unknowns = 0
var live = 0
cells.forEachIndexed { index, it ->
if (it == -1) unknowns += (weights?.get(index) ?: 1)
else if (it == 1) live += (weights?.get(index) ?: 1)
if (it == -1) unknowns += 1
else if (it == 1) live += 1
}

var count = 0
Expand All @@ -375,8 +377,11 @@ class HROTGenerations : BaseHROT {
}

var state = 0b00
if (count != 0) state += 0b10
if (count < unknowns + 1) state += 1 shl (cellState + 1).mod(numStates)
if (count != 0) state += 1 shl 1
if (count < unknowns + 1) {
if (cellState == 0) state += 1 shl 0
else state += 1 shl (cellState + 1).mod(numStates)
}

return state
} else {
Expand All @@ -402,7 +407,10 @@ class HROTGenerations : BaseHROT {

var state = 0b00
if (count != 0) state += 0b10
if (dead) state += 1 shl (cellState + 1).mod(numStates)
if (dead) {
if (cellState == 0) state += 1 shl 0
else state += 1 shl (cellState + 1).mod(numStates)
}

return state
}
Expand Down
20 changes: 12 additions & 8 deletions src/commonMain/kotlin/search/cfind/CFind.kt
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class CFind(

this[count.mod(period)] = period * k - count

val temp = this.toList()
val temp = this.toList() // TODO figure out why on Earth this is needed
temp.forEachIndexed { index, it -> this[(index + 1).mod(period)] = it }
}
val fwdOff = run {
Expand Down Expand Up @@ -766,7 +766,7 @@ class CFind(

if (depth <= this.lookaheadDepth[phase]) string
else gray(string)
} else " ".repeat(4*this@CFind.indices[0].size)
} else " ".repeat(4*this@CFind.indices[0].size - 1)
}.joinToString(bold(" | "))
)
}
Expand Down Expand Up @@ -1528,7 +1528,7 @@ class CFind(
if (successorLookahead[originalPhase][lookaheadDepth] > 0) {
val row = lookaheadRows[successorLookaheadIndex[originalPhase][lookaheadDepth] - lookaheadDepth]
val invert = symmetry == ShipSymmetry.GLIDE &&
(period.mod(2) == 0 && rows.last().phase == 0)
(period.mod(2) == 1 || rows.last().phase == 0)
if (invert) return (1 shl rule.numStates) - 1 // TODO fix this optimisation for glide-symmetric rules

val coordinate = translate(
Expand All @@ -1544,17 +1544,20 @@ class CFind(
val temp = it + coordinate
val state = row[temp, 0, null, depth]
key += (if (state == -1) rule.numStates else state) * power
key2 += (if (state == -1) 0 else state) * power2
power *= (rule.numStates + 1)
power2 *= rule.numStates

if (it !in baseCoordinates) {
key2 += (if (state == -1) 0 else state) * power2
power2 *= rule.numStates
}
}

val cellState = lookaheadRows.last()[coordinate, 0, null, depth]
val cellState = row[coordinate, 0, null, depth]
key += cellState * power
key2 += cellState * power2

if (successorLookahead[originalPhase][lookaheadDepth] == lookaheadDepth + 1)
_lookaheadMemo2!![it + additionalDepthArray[originalPhase]] = key2
_lookaheadMemo2!![it + additionalDepthArray[depth.mod(spacing)]] = key2

possibleSuccessorMemo[it] = approximateLookaheadTable[key]
} else {
Expand Down Expand Up @@ -1661,9 +1664,10 @@ class CFind(
index = tempCoordinate.x / spacing
} else index = tempCoordinate.x

// Getting the boundary state
if (it.y == -centralHeight) {
val lookupTable = lookup(index)

// Getting the boundary state
val boundaryState = rows[tempCoordinate, 0, cells, depth]

// Finally checking the boundary condition
Expand Down
2 changes: 2 additions & 0 deletions src/commonMain/kotlin/search/cfind/Row.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class Row(

// unique id for each row
val id = counter++

// TODO think harder about if this is actually correct
val depthPeriod = lcm(search!!.spacing, if (gcd(search!!.period, search!!.k) > 1) search!!.period else 1)

val hash = run {
Expand Down
24 changes: 18 additions & 6 deletions src/commonTest/kotlin/search/CFindTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.time.TimeSource

@Ignore
class Test {
private val searchStrategies = listOf(SearchStrategy.HYBRID_BFS, SearchStrategy.PRIORITY_QUEUE)

Expand Down Expand Up @@ -155,6 +154,8 @@ class Test {
verbosity = 1, searchStrategy = strategy
)
search.search()

assertEquals(search.searchResults.size, 3)
}
}

Expand Down Expand Up @@ -191,13 +192,12 @@ class Test {

assertEquals(glideDiagonalSearch.searchResults.size, 2)

val minibugsSearch = CFind(
HROT("R2,C2,S6-9,B7-8,NM"), 3, 1, 2, ShipSymmetry.ODD,
val p2search = CFind(
HROT("R2,C2,S2,B3,NN"), 2, 1, 6, ShipSymmetry.ODD,
verbosity = 1, searchStrategy = strategy, direction = Coordinate(1 ,1)
)
minibugsSearch.search()

assertEquals(minibugsSearch.searchResults.size, 1)
p2search.search()
assertEquals(p2search.searchResults.size, 21)
}
}

Expand Down Expand Up @@ -235,4 +235,16 @@ class Test {
assertEquals(photonSearch.searchResults.size, 1)
}
}

fun highPeriodTest() {
for (strategy in searchStrategies) {
val search = CFind(
HROT("R2,C2,S2,B3,NN"), 4, 2, 5, ShipSymmetry.ASYMMETRIC,
verbosity = 1, searchStrategy = strategy, numShips = 1
)
search.search()

assertEquals(search.searchResults.size, 1)
}
}
}
13 changes: 10 additions & 3 deletions src/jvmMain/kotlin/Main.jvm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import simulation.*
import java.io.File
import kotlin.random.Random
import patterns.Oscillator
import rules.hrot.HROTExtendedGenerations

actual fun main() {
// val rule = HROT("R2,C2,S6-9,14-20,B7-8,15-24,NM")
Expand Down Expand Up @@ -110,10 +111,16 @@ actual fun main() {
// B2-ei3cjkr4cektyz5-cnr6-ik78/S01e2-ae3cnqry4cqrtwyz5-ain6ekn7e
// B2ac3anr4-ijkz5cjkry6-cn7c8/S12i3aejy4nqtw5ceny6-kn7c
// HROT("R2,C2,S6-11,B4,9-11,NW0020003330230320333000200")
// val search = CFind(
// HROT("R2,C2,S2,B3,NN"), 4, 2, 5, ShipSymmetry.ASYMMETRIC,
// verbosity = 1, searchStrategy = SearchStrategy.HYBRID_BFS, numThreads = 8,
// //direction = Coordinate(1, 1), lookaheadDepth = 3, numShips = 30
// )
// search.search()

val search = CFind(
HROT("R2,C2,S6-11,B4,9-11,NW0020003330230320333000200"), 3, 1, 8, ShipSymmetry.ODD,
verbosity = 1, searchStrategy = SearchStrategy.PRIORITY_QUEUE, numThreads = 8,
direction = Coordinate(1, 1), lookaheadDepth = 3, numShips = 30
HROTGenerations("134/24/3"), 4, 3, 19, symmetry = ShipSymmetry.ODD,
verbosity = 1, searchStrategy = SearchStrategy.PRIORITY_QUEUE, lookaheadDepth = 1
)
search.search()
}

0 comments on commit ca91e37

Please sign in to comment.