Need help with 7'th last. Lesson 8#40
Need help with 7'th last. Lesson 8#40tiger31 wants to merge 28 commits intoKotlin-Polytech:masterfrom
Conversation
src/lesson1/task1/Simple.kt
Outdated
| */ | ||
| fun angleInRadian(grad: Int, min: Int, sec: Int): Double = TODO() | ||
| fun angleInRadian(grad: Int, min: Int, sec: Int): Double { | ||
| var value: Double = grad + min.toDouble()/60 + sec.toDouble()/3600; |
There was a problem hiding this comment.
- Данная переменная может быть объявлена как
val - Система типов Котлина выведет тип переменной автоматически
|
Как я понял последня задача седьмого урока решается графом + A*? Или есть другие пути её решения? |
|
Вы бы лучше сперва все замечания исправили, перед тем, как решать последнюю задачу седьмого урока. В целом, эту задачу можно решать поиском на неявно заданном графе, да. Вот только что у вас будет эвристикой для A*? |
|
Исправлениями я займусь, а эвристикой будет что-то вроде f(x)=(количество перестановок до текущего состояния + количество ячеек не на своём месте) |
|
recheck all |
|
Изменил эвристику и пуллинг новых вершин, но алгоритм все еще решает только простые задачи с небольшим количество ходов. Что не так в алгоритме? |
|
Я знаю, что он и не вернет список ходов, но он даже не может найти конечную вершину(решение) |
mglukhikh
left a comment
There was a problem hiding this comment.
Я взял на себя смелость поревьюить fifteenGameSolution (и только её), поскольку вы первый из студентов, кто пытается решить эту задачу. Ответ на ваш вопрос в ревью содержится. Дерзайте. Эта задача, по-видимому, самая сложная во всём проекте, так что не огорчайтесь, если не получится решить её быстро. Если у моих коллег есть дополнительные замечания к решению, они напишут их отдельно.
NB: не считайте, пожалуйста, что вначале надо заставить всё работать, а потом решение причёсывать и приводить в порядок стиль. В нормальном случае эти процессы идут параллельно, поскольку заставить работать аккуратно написанное решение проще. Многократно проверено.
src/lesson7/task2/Matrices.kt
Outdated
| listOf(9, 10, 11, 12), | ||
| listOf(13, 15, 14, 0))) | ||
|
|
||
| fun h(matrix: Matrix<Int>): Int { |
There was a problem hiding this comment.
Старайтесь не называть так функции. Насколько я понимаю, эта функция возвращает некоторую оценку, насколько далеко данная позиция от исходной. В соответствии с этим придумайте название. Простой идеей может быть, например, evaluation (оценка)
src/lesson7/task2/Matrices.kt
Outdated
|
|
||
| fun h(matrix: Matrix<Int>): Int { | ||
| var n = 0 | ||
| for (i in 0..3) |
There was a problem hiding this comment.
В таких конструкциях лучше ставить фигурные скобки везде, иначе их тяжелее читать. Кроме этого, есть смысл назвать в данном случае переменные цикла row и column -- так понятнее.
src/lesson7/task2/Matrices.kt
Outdated
| var n = 0 | ||
| for (i in 0..3) | ||
| for (j in 0..3) | ||
| if (matrix[i,j] != 0) |
There was a problem hiding this comment.
Вот здесь я не уверен в разумности этой проверки. Интуиция подсказывает, что расстояние пустой ячейки от её оригинальной позиции тоже имеет некоторое значение. Но здесь, конечно, нужна проверка на практике.
src/lesson7/task2/Matrices.kt
Outdated
| for (j in 0..3) | ||
| if (matrix[i,j] != 0) | ||
| if (matrix[i,j] != i * 4 + j + 1) { | ||
| n += abs(matrix[i, j] / 4 - i) + abs(matrix[i, j] % 4 - j - 1) |
There was a problem hiding this comment.
Насколько я понимаю, здесь вы пытаетесь посчитать сумму расстояний по горизонтали и вертикали от оригинальной позиции. Если это так, то использованная формула кажется мне неверной.
src/lesson7/task2/Matrices.kt
Outdated
| for (j in 0..i - 1) | ||
| if (list[j] > list[i]) | ||
| N++ | ||
| } else N += 1 + i / 4 |
There was a problem hiding this comment.
Вы уверены, что этот кусок формулы, касающийся пустой клетки, справедлив? (спрашиваю потому, что первую часть этого мини-алгоритма в математических книгах я видел, а вторую -- нет)
There was a problem hiding this comment.
Кроме этого, это определение чётности позиции стоило бы вынести в отдельную функцию
src/lesson7/task2/Matrices.kt
Outdated
| val solution = if (N % 2 == 0) solution1 else solution2 | ||
| println("Solution: \r\n $solution") | ||
|
|
||
| // Попытка A* + поиск в шиину |
There was a problem hiding this comment.
Всё начиная отсюда стоило бы вытащить в отдельную функцию. Кроме этого, A* пока не виден
src/lesson7/task2/Matrices.kt
Outdated
| println("Solution: \r\n $solution") | ||
|
|
||
| // Попытка A* + поиск в шиину | ||
| data class State(val m: Matrix<Int>, val priority: Int) : Comparable<State> { |
There was a problem hiding this comment.
m --> matrix. Такие короткие имена почти не используются для свойств
src/lesson7/task2/Matrices.kt
Outdated
| queue.add(State(matrix, h(matrix))) | ||
|
|
||
| val visited = mutableMapOf(matrix to 0) | ||
| while (queue.isNotEmpty()) { |
There was a problem hiding this comment.
Я боюсь, что с подобной идеей алгоритма исправление ошибок (например, не учитывается приоритет, не запоминаются ходы, может быть, я ещё чего-либо не вижу) не поможет. Дело в том, что у игры в 15 всего имеется 16! позиций, чёт / нечёт уменьшает это число вдвое. Такой вот полный поиск в ширину будет вынужден обойти весьма существенную часть от этого количества, а оно измеряется триллионами. То есть шансов получить решение за обозримое время таким способом вроде как не имеется (IMHO).
Что можно рекомендовать:
- в данной задаче
DFSдолжен быть лучшеBFS, хотя бы за счёт того, что можно избежать постоянного копирования матриц - независимо от того, используете вы
DFSилиBFS, поиск необходимо ограничивать, то есть не искать дальше, чем на какое-то ограниченное количество ходов вперёд; вы при этом не достигнете завершающей позиции, но сможете найти позицию с лучшей оценкой и ход, ведущий в неё; найденный ход следует запомнить в списке, сделать и повторить всю процедуру поиска уже с новой позиции для поиска лучшего второго хода; процедура повторяется до тех пор, пока сделанный ход не приведёт вас вsolution.
|
Очень много неисправленных ранее замечаний. Давайте вы сперва исправите их все (да, скучно, да, нудно, да, не приближает вас к получению зачета напрямую), а потом уже будем смотреть, что вы наделали дальше. |
… not the 65-steps example given
authortiger31 [tiger31839@gmail.com] ownertiger31 [] |
ice-phoenix
left a comment
There was a problem hiding this comment.
Чего-то посмотрел и пописал в задачке про 15
src/lesson7/task2/Matrices.kt
Outdated
| n += abs(matrix[i, j] / 4 - i) + abs(matrix[i, j] % 4 - j - 1) | ||
| class State(val matrix: Matrix<Int>, val moved: Int?) { | ||
|
|
||
| object companion { |
There was a problem hiding this comment.
Вообще-то, companion object задается несколько не так
|
|
||
| //Extensions of Cell data class | ||
| // По-нормальноу это должен быть статический параметр класса, но са класс Cell я менять не могу | ||
| val NOT_EXISTS = Cell(-1, -1) |
There was a problem hiding this comment.
Вы не поверите, но можно сделать extension value у класса =)
| val NOT_EXISTS = Cell(-1, -1) | ||
|
|
||
| fun Cell.near(other: Cell): Boolean { | ||
| if (this == other) throw IllegalArgumentException("Cells are the same") |
|
|
||
| fun <E> Matrix<E>.subMatrix(height: Int, width: Int, heightShift: Int, widthShift: Int): Matrix<E> { | ||
| if (this.height < height + heightShift || this.width < width + widthShift) | ||
| throw IllegalArgumentException("Sub Matrix is out of bounds of original") |
There was a problem hiding this comment.
Раз уж мы все проверяем, то я бы проверил границы и в другую сторону
| fun <E> Matrix<E>.contains(cell: Cell): Boolean = this.contains(cell.row, cell.column) | ||
|
|
||
| fun <E> Matrix<E>.subMatrix(height: Int, width: Int, heightShift: Int, widthShift: Int): Matrix<E> { | ||
| if (this.height < height + heightShift || this.width < width + widthShift) |
There was a problem hiding this comment.
Тут у вас клэш по именам, лучше его избегать --- я бы переименовал аргументы функции как-нибудь по другому
| } | ||
| } | ||
| } | ||
| state.matrix.swap(zero, move) |
There was a problem hiding this comment.
Кажется, что во всем этом деле (см. выше) вы слишком много раз копируете матрицу там, где можно было бы обойтись и без этого
| var solved = false | ||
|
|
||
| if (state.matrix == State.companion.SOLUTION) | ||
| return listOf() |
There was a problem hiding this comment.
Вы уж разберитесь в коде, либо через ==, либо через solved
src/lesson7/task2/Matrices.kt
Outdated
| println("$count searches are complete, pathes = $finished, current depth = $limit, visited = ${visited.size}") | ||
| limit += 2 | ||
| visited.clear() | ||
| moves.clear() |
There was a problem hiding this comment.
Зачем перезапускать поиск с нуля?
src/lesson7/task2/Matrices.kt
Outdated
|
|
||
| fun fifteenGameSolution(matrix: Matrix<Int>): List<Int> { | ||
|
|
||
| State.companion.START = matrix |
There was a problem hiding this comment.
По хорошему, вам надо завести класс Solver, который будет заниматься хранением всей нужной вам для решения одного экземпляра задачи информации, а не жонглировать статическими переменными налево и направо
src/lesson7/task2/Matrices.kt
Outdated
| } else { | ||
|
|
||
| if (!visited.contains(state.matrix.copyN())) { | ||
| if (state.estimate() + path + 1 > limit) { |
There was a problem hiding this comment.
Зачем вы вообще ограничиваете глубину поиска, чтобы потом (если не получилось) перезапускать все с нуля и снова проходить все те же самые позиции?
|
recheck all |
|
Несмотря на большое количество замечаний и не очень чистый код, по совокупной статистике решения задач и результатам тестирования у вас "Отлично"! Так держать! |
|
PS: Но тесты все же лучше, чтобы завершались =) |
authortiger31 [tiger31839@gmail.com] ownertiger31 [] |
|
Я сейчас несколько исправлений еще добавляю. Очень хотелось бы увидеть правильное решение последней задачи в седьмом, потому что пока это единственная задача, которая меня "сломала" :) |
authortiger31 [tiger31839@gmail.com] lesson7.task2Author: tiger31 [tiger31839@gmail.com] Owner: tiger31 [] Total: 14 / 15 Example: 2 / 2 Succeeded:
Seed: 4571634249296578062 lesson8.task1Author: tiger31 [tiger31839@gmail.com] Owner: tiger31 [] Total: 4 / 13 Example: 1 / 1 Succeeded:
Failed:
Seed: 4571634249296578062 ownertiger31 [] totalAuthor: tiger31 [tiger31839@gmail.com] Owner: tiger31 [] Total: 18 / 28 Example: 3 / 3 |
Check out 1st, 2nd, 3rd lessons, 4th in progress