-
Notifications
You must be signed in to change notification settings - Fork 102
Need help with 7'th last. Lesson 8 #40
Conversation
|
||
/** | ||
* Тривиальная | ||
* | ||
* Пользователь задает угол в градусах, минутах и секундах (например, 36 градусов 14 минут 35 секунд). | ||
* Вывести значение того же угла в радианах (например, 0.63256). | ||
*/ | ||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Данная переменная может быть объявлена как
val
- Система типов Котлина выведет тип переменной автоматически
Как я понял последня задача седьмого урока решается графом + A*? Или есть другие пути её решения? |
Вы бы лучше сперва все замечания исправили, перед тем, как решать последнюю задачу седьмого урока. В целом, эту задачу можно решать поиском на неявно заданном графе, да. Вот только что у вас будет эвристикой для A*? |
Исправлениями я займусь, а эвристикой будет что-то вроде f(x)=(количество перестановок до текущего состояния + количество ячеек не на своём месте) |
recheck all |
Изменил эвристику и пуллинг новых вершин, но алгоритм все еще решает только простые задачи с небольшим количество ходов. Что не так в алгоритме? |
Я знаю, что он и не вернет список ходов, но он даже не может найти конечную вершину(решение) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Я взял на себя смелость поревьюить fifteenGameSolution
(и только её), поскольку вы первый из студентов, кто пытается решить эту задачу. Ответ на ваш вопрос в ревью содержится. Дерзайте. Эта задача, по-видимому, самая сложная во всём проекте, так что не огорчайтесь, если не получится решить её быстро. Если у моих коллег есть дополнительные замечания к решению, они напишут их отдельно.
NB: не считайте, пожалуйста, что вначале надо заставить всё работать, а потом решение причёсывать и приводить в порядок стиль. В нормальном случае эти процессы идут параллельно, поскольку заставить работать аккуратно написанное решение проще. Многократно проверено.
listOf(9, 10, 11, 12), | ||
listOf(13, 15, 14, 0))) | ||
|
||
fun h(matrix: Matrix<Int>): Int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Старайтесь не называть так функции. Насколько я понимаю, эта функция возвращает некоторую оценку, насколько далеко данная позиция от исходной. В соответствии с этим придумайте название. Простой идеей может быть, например, evaluation
(оценка)
|
||
fun h(matrix: Matrix<Int>): Int { | ||
var n = 0 | ||
for (i in 0..3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
В таких конструкциях лучше ставить фигурные скобки везде, иначе их тяжелее читать. Кроме этого, есть смысл назвать в данном случае переменные цикла row
и column
-- так понятнее.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вот здесь я не уверен в разумности этой проверки. Интуиция подсказывает, что расстояние пустой ячейки от её оригинальной позиции тоже имеет некоторое значение. Но здесь, конечно, нужна проверка на практике.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Насколько я понимаю, здесь вы пытаетесь посчитать сумму расстояний по горизонтали и вертикали от оригинальной позиции. Если это так, то использованная формула кажется мне неверной.
for (j in 0..i - 1) | ||
if (list[j] > list[i]) | ||
N++ | ||
} else N += 1 + i / 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вы уверены, что этот кусок формулы, касающийся пустой клетки, справедлив? (спрашиваю потому, что первую часть этого мини-алгоритма в математических книгах я видел, а вторую -- нет)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Кроме этого, это определение чётности позиции стоило бы вынести в отдельную функцию
val solution = if (N % 2 == 0) solution1 else solution2 | ||
println("Solution: \r\n $solution") | ||
|
||
// Попытка A* + поиск в шиину |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Всё начиная отсюда стоило бы вытащить в отдельную функцию. Кроме этого, A*
пока не виден
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m
--> matrix
. Такие короткие имена почти не используются для свойств
queue.add(State(matrix, h(matrix))) | ||
|
||
val visited = mutableMapOf(matrix to 0) | ||
while (queue.isNotEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Я боюсь, что с подобной идеей алгоритма исправление ошибок (например, не учитывается приоритет, не запоминаются ходы, может быть, я ещё чего-либо не вижу) не поможет. Дело в том, что у игры в 15 всего имеется 16!
позиций, чёт / нечёт уменьшает это число вдвое. Такой вот полный поиск в ширину будет вынужден обойти весьма существенную часть от этого количества, а оно измеряется триллионами. То есть шансов получить решение за обозримое время таким способом вроде как не имеется (IMHO).
Что можно рекомендовать:
- в данной задаче
DFS
должен быть лучшеBFS
, хотя бы за счёт того, что можно избежать постоянного копирования матриц - независимо от того, используете вы
DFS
илиBFS
, поиск необходимо ограничивать, то есть не искать дальше, чем на какое-то ограниченное количество ходов вперёд; вы при этом не достигнете завершающей позиции, но сможете найти позицию с лучшей оценкой и ход, ведущий в неё; найденный ход следует запомнить в списке, сделать и повторить всю процедуру поиска уже с новой позиции для поиска лучшего второго хода; процедура повторяется до тех пор, пока сделанный ход не приведёт вас вsolution
.
Очень много неисправленных ранее замечаний. Давайте вы сперва исправите их все (да, скучно, да, нудно, да, не приближает вас к получению зачета напрямую), а потом уже будем смотреть, что вы наделали дальше. |
… not the 65-steps example given
authortiger31 [[email protected]] ownertiger31 [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Чего-то посмотрел и пописал в задачке про 15
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вообще-то, companion object задается несколько не так
|
||
// Все задачи в этом файле требуют наличия реализации интерфейса "Матрица" в Matrix.kt | ||
|
||
//Extensions of Cell data class | ||
// По-нормальноу это должен быть статический параметр класса, но са класс Cell я менять не могу | ||
val NOT_EXISTS = Cell(-1, -1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вы не поверите, но можно сделать extension value у класса =)
val NOT_EXISTS = Cell(-1, -1) | ||
|
||
fun Cell.near(other: Cell): Boolean { | ||
if (this == other) throw IllegalArgumentException("Cells are the same") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Можно в виде one-liner
|
||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Раз уж мы все проверяем, то я бы проверил границы и в другую сторону
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут у вас клэш по именам, лучше его избегать --- я бы переименовал аргументы функции как-нибудь по другому
} | ||
} | ||
} | ||
state.matrix.swap(zero, move) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Кажется, что во всем этом деле (см. выше) вы слишком много раз копируете матрицу там, где можно было бы обойтись и без этого
var solved = false | ||
|
||
if (state.matrix == State.companion.SOLUTION) | ||
return listOf() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вы уж разберитесь в коде, либо через ==
, либо через solved
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Зачем перезапускать поиск с нуля?
|
||
fun fifteenGameSolution(matrix: Matrix<Int>): List<Int> { | ||
|
||
State.companion.START = matrix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
По хорошему, вам надо завести класс Solver
, который будет заниматься хранением всей нужной вам для решения одного экземпляра задачи информации, а не жонглировать статическими переменными налево и направо
} else { | ||
|
||
if (!visited.contains(state.matrix.copyN())) { | ||
if (state.estimate() + path + 1 > limit) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Зачем вы вообще ограничиваете глубину поиска, чтобы потом (если не получилось) перезапускать все с нуля и снова проходить все те же самые позиции?
recheck all |
Несмотря на большое количество замечаний и не очень чистый код, по совокупной статистике решения задач и результатам тестирования у вас "Отлично"! Так держать! |
PS: Но тесты все же лучше, чтобы завершались =) |
authortiger31 [[email protected]] ownertiger31 [] |
Я сейчас несколько исправлений еще добавляю. Очень хотелось бы увидеть правильное решение последней задачи в седьмом, потому что пока это единственная задача, которая меня "сломала" :) |
authortiger31 [[email protected]] lesson7.task2Author: tiger31 [[email protected]] Owner: tiger31 [] Total: 14 / 15 Example: 2 / 2 Succeeded:
Seed: 4571634249296578062 lesson8.task1Author: tiger31 [[email protected]] Owner: tiger31 [] Total: 4 / 13 Example: 1 / 1 Succeeded:
Failed:
Seed: 4571634249296578062 ownertiger31 [] totalAuthor: tiger31 [[email protected]] Owner: tiger31 [] Total: 18 / 28 Example: 3 / 3 |
Check out 1st, 2nd, 3rd lessons, 4th in progress