powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / задача конем шахматной доски.
74 сообщений из 74, показаны все 3 страниц
задача конем шахматной доски.
    #39371437
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.

Попинали в другой теме, посоветовали открыть новую.

Вот такая классика интересная :

Требуется реализовать задачу обхода шахматного коня всей шахматной доски 8x8 из клетки (i,j) так, чтобы в каждой клетке он(конь) побывал ровно по одному разу.
Способ реализации мультипоточный 4 - потока = const (можно и больше, не принципиально, лишь бы найти решение(я)). алгоритм - методом обхода в глубину .
Исходные данные:
4 (или более) потока(константа) - задано жестко в программе.
M - минимальное число маршрутов коня которые нужно найти.
i,j - стартовая точка.
M,i,j - задаются в виде аргументов командной строки.

правилом Варнсдорфа не пользуемся , так как оно работает - реализация удалась (во всяком случае для 8x8 и даже более , так что не интересно)
Как я понял в другой теме товарищ (а он наверняка прочитает и меня подправит) предложил выбирать не последовательно ветки , а в случайном порядке, откатываясь назад к предку при случае , если конь упёрся в тупик. делать это он предлагал параллельно в нескольких потоках, чтобы стратегия хода была разная (выбор ведь будет случайным ).
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371438
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,

блин, в теме лоханулся. сорри - у меня вечер туго думаю )
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371490
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тишина какая-то. Ну ладно. Для затравки.

Код: java
1.
2.
3.
4.
5.
public static void main(String[] args) throws Exception {

         Executor executor = Executors.newFixedThreadPool(4);

}
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371520
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonТишина какая-то.

О, да! В 2 часа ночи никто не подорвался решать за тебя курсовую. Тишина в теме, никому не хочется работать

Блин, раньше в delphi-форумах такое было "решите курсач, срочно", теперь вот начали в ПТУ java учить- и здесь постоянно лезет.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371532
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin, ой да не смешите. в ПТУ меня не примут. старый я уже.

не надо за меня ничего делать. задача уже как 3 недели мною решена , причем 2-мя методами. один из которых Варнсдорф - даёт решения. а второй затыкается на разросшимся дереве (вариантов очень много)

Меня заинтриговал mayton , он полагает, что возможно решить задачу при помощи многопоточности. у меня так не получается. особенности алгоритма я и хотел обсудить.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371541
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81он полагает, что возможно решить задачу при помощи многопоточности. у меня так не получается. особенности алгоритма я и хотел обсудить.

Если стоит цель "распараллелить" то я вижу два рпшения:
1. Только в 4 потока. Начинаем с поля Е1 (начинать можно с любого). И запускаем 4 потока, в первом первый ход на C2, во втором- на D3, потом не F3 и G2. Потом надо подчистить симметричные потоки.
2. Говорим "а фигли там", делаем таску "начать с поля A1 и первых ход на C2" и каждый ход создаёт новую таску на все допустимые ходы и пихает их в тредпул. Это если ход есть. Если нет- либо записывает путь, либо (нет решения) просто завершает задачу. A1->C2 чтобы потом бубли (обратные решения) не удалять.
3. В 5 потоков . Каждый начинает с A1->C2 а далее 5 возможных ходов.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371546
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вы пишите , что видите 2 решения , но у вас 3 пункта. это как мне понимать ?

Alexey Tomin1. Только в 4 потока. Начинаем с поля Е1 (начинать можно с любого). И запускаем 4 потока, в первом первый ход на C2, во втором- на D3, потом не F3 и G2. Потом надо подчистить симметричные потоки.


что значит считаем симметричные потоки ?

Alexey Tomin2. Говорим "а фигли там", делаем таску "начать с поля A1 и первых ход на C2" и каждый ход создаёт новую таску на все допустимые ходы и пихает их в тредпул. Это если ход есть. Если нет- либо записывает путь, либо (нет решения) просто завершает задачу. A1->C2 чтобы потом бубли (обратные решения) не удалять.

объясните, что значит "таск" ???



каким образом вы выбираете какой ход сделать во всех способах ?
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371581
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81Alexey Tomin, ой да не смешите. в ПТУ меня не примут. старый я уже.

не надо за меня ничего делать. задача уже как 3 недели мною решена , причем 2-мя методами. один из которых Варнсдорф - даёт решения. а второй затыкается на разросшимся дереве (вариантов очень много).
КМК Варнсдорф играет на том что доска 8x8 - маленькая и его правило срабатывает часто
за счет границ доски. Если мы возьмем доску 100х100 к примеру то мне кажется в таком
случае разница между поиском в глубину и Варнсдорфом не будет такая очевидная.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371590
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonandron81Alexey Tomin, ой да не смешите. в ПТУ меня не примут. старый я уже.

не надо за меня ничего делать. задача уже как 3 недели мною решена , причем 2-мя методами. один из которых Варнсдорф - даёт решения. а второй затыкается на разросшимся дереве (вариантов очень много).
КМК Варнсдорф играет на том что доска 8x8 - маленькая и его правило срабатывает часто
за счет границ доски. Если мы возьмем доску 100х100 к примеру то мне кажется в таком
случае разница между поиском в глубину и Варнсдорфом не будет такая очевидная.

он для доски 40x40 по-моему отрабатывает (и довольно быстро) , дальше затыкается. но дело даже только в этом. Забудьте про Варнсдорф. Интересен поиск в глубину.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371595
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81maytonпропущено...

КМК Варнсдорф играет на том что доска 8x8 - маленькая и его правило срабатывает часто
за счет границ доски. Если мы возьмем доску 100х100 к примеру то мне кажется в таком
случае разница между поиском в глубину и Варнсдорфом не будет такая очевидная.

он для доски 40x40 по-моему отрабатывает (и довольно быстро) , дальше затыкается. но дело даже только в этом. Забудьте про Варнсдорф. Интересен поиск в глубину.
Что значит - затыкается? Это не инженерный термин. Скорее всего метод работает.
Просто долго не выдает результата. А почему долго не выдаёт?

Вот это вопрос.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371597
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81вы пишите , что видите 2 решения , но у вас 3 пункта. это как мне понимать ?

Третье в последний момент придумал.

andron81что значит считаем симметричные потоки ?
Правильно "симметричные решения". Т.е. если одно боратно второму- то я ыб посчитал их одним решением. Хотя как хочется.

Alexey Tomin2. Говорим "а фигли там", делаем таску "начать с поля A1 и первых ход на C2" и каждый ход создаёт новую таску на все допустимые ходы и пихает их в тредпул. Это если ход есть. Если нет- либо записывает путь, либо (нет решения) просто завершает задачу. A1->C2 чтобы потом бубли (обратные решения) не удалять.

объясните, что значит "таск" ??? [/quote]

Это Runnable, который передаётся в Executor.execute()

andron81каким образом вы выбираете какой ход сделать во всех способах ?
Текущее поле - i,j
Перебираем все 8 доступных новых поля, отсекаем те, что за доской и те, что уже были (каждой таске надо передать, к примеру, массив уже пройденых полей).
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371606
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey TominПравильно "симметричные решения". Т.е. если одно боратно второму- то я ыб посчитал их одним решением. Хотя как хочется.

Да. Все верно. В задаче Эйлера о ферзях тоже было условие что расстановки
зеркальные друг относительно друга а также развороты на 90 градусов считаются
одинаковым решением.

И хотя в случае коня у нас есть начало и конец пути я все равно-бы рассматривал
такие пути безотносительно к порядку и просто как маршруты в общей базе уникальных
маршрутов.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371609
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
наверно разница между обычным в глубину алгоритмом и методом Варнсдорфом на больших полях пропадает.
но нет надобности такие большие поля юзать. задача стоит 8x8 - алгоритмом в глубину. всё !

вот человек правда на плюсах делает с графической иллюстрацией , на доске начиная со стороной 60 не выходит у него. посмотреть можно примерно с 7:03.
[youtube=
YouTube Video
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371628
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey TominТретье в последний момент придумал.

понял.
Alexey TominПравильно "симметричные решения".

тогда понятно.
да черт уже с ним, пусть даже это будут кое-где не уникальные решения в разных потоках. пусть они даже где-нибудь повторятся повторятся . не говоря уже о симметрии.


Alexey TominТекущее поле - i,j
Перебираем все 8 доступных новых поля, отсекаем те, что за доской и те, что уже были (каждой таске надо передать, к примеру, массив уже пройденых полей).


так я и делал. в этом случае для некоторых начальных точек дерево разрастается так, что даже для доски 8x8 и пол. дня для нормального компа не хватает чтобы выдать хоть одно решение.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39371653
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81
Alexey TominТекущее поле - i,j
Перебираем все 8 доступных новых поля, отсекаем те, что за доской и те, что уже были (каждой таске надо передать, к примеру, массив уже пройденых полей).


так я и делал. в этом случае для некоторых начальных точек дерево разрастается так, что даже для доски 8x8 и пол. дня для нормального компа не хватает чтобы выдать хоть одно решение.

стоп. соврал. проверять в разных потоках я не проверял. я каждый раз из 8 ходов выбирал ход случайным образом и если он свободен - делал ход.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39372010
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,

вообще меня вот настораживает , что мой обычный однопоточный алгоритм поиска в глубину (без Варнсдорфа) не находит решений даже минут за 5 с начальной клетки 1:2 , с клетки 5:5. Причем на находит и продолжает думать. хотя вот с клетки 1:1 находит. может где - то всё же логика моего алгоритма даёт дурака.

я вижу 2 всё же варианта разобраться :
1. можно попробовать протоколировать как выражались весь флуд в файл;
2. попробовать как мужик на ютьюбе рисовать на шахматной доске траектории хода.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39372019
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81andron81,
вообще меня вот настораживает , что мой обычный однопоточный алгоритм поиска в глубину (без Варнсдорфа) не находит решений даже минут за 5 с начальной клетки 1:2 , с клетки 5:5.


даже за 15 минут
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373018
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81andron81andron81,
вообще меня вот настораживает , что мой обычный однопоточный алгоритм поиска в глубину (без Варнсдорфа) не находит решений даже минут за 5 с начальной клетки 1:2 , с клетки 5:5.


даже за 15 минут

Можно вопросец? В предыдушей ветке была формулировка задачи:

Требуется реализовать задачу обхода шахматного коня всей шахматной доски 8x8
из клетки (i,j) так, чтобы в каждой клетке он побывал ровно по одному разу .
Способ реализации мультипоточный (4 - потока = const) алгоритм методом обхода в глубину .
Исходные данные:
4 потока(константа) - задано жестко в программе.
M - минимальное число маршрутов коня которые нужно найти.
i,j - стартовая точка.

M,i,j - задаются в виде аргументов командной строки.

Так как конь должен побывать в каждой клетке доски и ровно один то это задача обхода дерева 64 слоя (количество ходов равно количеству клеток). Решений может быть больше одного но мы сосредоточимся на поиске первого решения, значит потребуется

а) Описание дерева и текушее состояние пути обхода
в) задание для обходчиков в отд потоках (для начала в одном потоке)

На каждом шаге конь имеет максимум 7 (кроме первого хода) вариантов хода (нельзя возвращаться в предыдущую клетку). На первом шаге может быть 8 вариантов.

Итого получаем дерево ходов 64 слоя, по 7 вариантов в каждом ноде, полный перебор всех вариантов составит 7 в 64 степени или 1.2197605e+54. При переборе 1млн вариантов в секунду количество секунд все равно неприлично большое. 4 или 400 потоков здесь не будут иметь решающего значения по сравнению с 1м.

Вопрос: точно требуется чтобы конь побывал в каждой клетке доски ровно один раз? Или требуется чтобы он на свои предыдущие ходы не попадал с заданым количеством шагов (меньше чем 64)?
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373106
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid uniqueВопрос: точно требуется чтобы конь побывал в каждой клетке доски ровно один раз? Или требуется чтобы он на свои предыдущие ходы не попадал с заданым количеством шагов (меньше чем 64)?


да. в каждой клетке один раз. это классическая задача .

uid uniqueНа каждом шаге конь имеет максимум 7 (кроме первого хода) вариантов хода

почему 7 ? от 8 и меньше !


uid uniqueИтого получаем дерево ходов 64 слоя, по 7 вариантов в каждом ноде, полный перебор всех вариантов составит 7 в 64 степени или 1.2197605e+54. При переборе 1млн вариантов в секунду количество секунд все равно неприлично большое. 4 или 400 потоков здесь не будут иметь решающего значения по сравнению с 1м.

люди говорят писали программы кот. находили решения за 5-10 мин. при помощи потоков не прибегая к помощи Варнсдорфа
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373289
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot andron81]
почему 7 ? от 8 и меньше !
8 только в первом ходу может быть, ведь в каждой точке можно только один раз поставить коня, значит на предыдущую клетку возвращаться нельзя, те максимум 7 вариантов.

andron81люди говорят писали программы кот. находили решения за 5-10 мин. при помощи потоков не прибегая к помощи Варнсдорфа
Вариантов конечно будет меньше, это верхняя оценка 7 в 64, но в любом случае перебором решать не стоит, число будет большим.
Глянул в сети, оценка 4*10^51. Это много в любом случае, вариант перебора тупиковый.

Кроме Вансдорфа, на вики нашел решение с нейронной сетью и бэттрейсинг вариант для доски 8х8.
Начальные условия только нужно пробросить.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
public class KnightTour {

	int[][] solution;
	int path = 0;

	public KnightTour(int N) {
		solution = new int[N][N];
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				solution[i][j] = 0;
			}
		}
	}

	public void solve() {
		if (findPath(0, 0, 0, solution.length)) {
			print();
		} else {
			System.out.println("NO PATH FOUND");
		}
	}

	public boolean findPath(int row, int column, int index, int N) {
		// check if current is not used already
		if (solution[row][column] != 0) {
			return false;
		}
		// mark the current cell is as used
		solution[row][column] = path++;
		// if (index == 50) {
		if (index == N * N - 1) {
			// if we are here means we have solved the problem
			return true;
		}
		// try to solve the rest of the problem recursively

		// go down and right
		if (canMove(row + 2, column + 1, N)
				&& findPath(row + 2, column + 1, index + 1, N)) {
			return true;
		}
		// go right and down
		if (canMove(row + 1, column + 2, N)
				&& findPath(row + 1, column + 2, index + 1, N)) {
			return true;
		}
		// go right and up
		if (canMove(row - 1, column + 2, N)
				&& findPath(row - 1, column + 2, index + 1, N)) {
			return true;
		}
		// go up and right
		if (canMove(row - 2, column + 1, N)
				&& findPath(row - 2, column + 1, index + 1, N)) {
			return true;
		}
		// go up and left
		if (canMove(row - 2, column - 1, N)
				&& findPath(row - 2, column - 1, index + 1, N)) {
			return true;
		}
		// go left and up
		if (canMove(row - 1, column - 2, N)
				&& findPath(row - 1, column - 2, index + 1, N)) {
			return true;
		}
		// go left and down
		if (canMove(row + 1, column - 2, N)
				&& findPath(row + 1, column - 2, index + 1, N)) {
			return true;
		}
		// go down and left
		if (canMove(row + 2, column - 1, N)
				&& findPath(row + 2, column - 1, index + 1, N)) {
			return true;
		}
		// if we are here means nothing has worked , backtrack
		solution[row][column] = 0;
		path--;
		return false;

	}

	public boolean canMove(int row, int col, int N) {
		if (row >= 0 && col >= 0 && row < N && col < N) {
			return true;
		}
		return false;
	}

	public void print() {
		DecimalFormat twodigits = new DecimalFormat("00");
		for (int i = 0; i < solution.length; i++) {
			for (int j = 0; j < solution.length; j++) {
				System.out.print("   " + twodigits.format(solution[i][j]));
			}
			System.out.println();
		}
	}

	public static void main(String[] args) {
		int N = 8;
		KnightTour i = new KnightTour(N);
		i.solve();
	}

}
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373294
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм... Не поверишь но я вчера то же решение нагуглил. По наделал столько изменений - теперь не корректно работает.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373319
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot uid unique]andron81почему 7 ? от 8 и меньше !
8 только в первом ходу может быть, ведь в каждой точке можно только один раз поставить коня, значит на предыдущую клетку возвращаться нельзя, те максимум 7 вариантов.

пропущено...

Вариантов конечно будет меньше, это верхняя оценка 7 в 64, но в любом случае перебором решать не стоит, число будет большим.
Глянул в сети, оценка 4*10^51. Это много в любом случае, вариант перебора тупиковый.

Кроме Вансдорфа, на вики нашел решение с нейронной сетью и бэттрейсинг вариант для доски 8х8.
Начальные условия только нужно пробросить.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
public class KnightTour {

	int[][] solution;
	int path = 0;

	public KnightTour(int N) {
		solution = new int[N][N];
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				solution[i][j] = 0;
			}
		}
	}

	public void solve() {
		if (findPath(0, 0, 0, solution.length)) {
			print();
		} else {
			System.out.println("NO PATH FOUND");
		}
	}

	public boolean findPath(int row, int column, int index, int N) {
		// check if current is not used already
		if (solution[row][column] != 0) {
			return false;
		}
		// mark the current cell is as used
		solution[row][column] = path++;
		// if (index == 50) {
		if (index == N * N - 1) {
			// if we are here means we have solved the problem
			return true;
		}
		// try to solve the rest of the problem recursively

		// go down and right
		if (canMove(row + 2, column + 1, N)
				&& findPath(row + 2, column + 1, index + 1, N)) {
			return true;
		}
		// go right and down
		if (canMove(row + 1, column + 2, N)
				&& findPath(row + 1, column + 2, index + 1, N)) {
			return true;
		}
		// go right and up
		if (canMove(row - 1, column + 2, N)
				&& findPath(row - 1, column + 2, index + 1, N)) {
			return true;
		}
		// go up and right
		if (canMove(row - 2, column + 1, N)
				&& findPath(row - 2, column + 1, index + 1, N)) {
			return true;
		}
		// go up and left
		if (canMove(row - 2, column - 1, N)
				&& findPath(row - 2, column - 1, index + 1, N)) {
			return true;
		}
		// go left and up
		if (canMove(row - 1, column - 2, N)
				&& findPath(row - 1, column - 2, index + 1, N)) {
			return true;
		}
		// go left and down
		if (canMove(row + 1, column - 2, N)
				&& findPath(row + 1, column - 2, index + 1, N)) {
			return true;
		}
		// go down and left
		if (canMove(row + 2, column - 1, N)
				&& findPath(row + 2, column - 1, index + 1, N)) {
			return true;
		}
		// if we are here means nothing has worked , backtrack
		solution[row][column] = 0;
		path--;
		return false;

	}

	public boolean canMove(int row, int col, int N) {
		if (row >= 0 && col >= 0 && row < N && col < N) {
			return true;
		}
		return false;
	}

	public void print() {
		DecimalFormat twodigits = new DecimalFormat("00");
		for (int i = 0; i < solution.length; i++) {
			for (int j = 0; j < solution.length; j++) {
				System.out.print("   " + twodigits.format(solution[i][j]));
			}
			System.out.println();
		}
	}

	public static void main(String[] args) {
		int N = 8;
		KnightTour i = new KnightTour(N);
		i.solve();
	}

}



с точки 0,0 (1,1) и у меня находит обычный обход доски неплохо обычным перебором. а вот с точки 1,0 и этот алгоритм уходит в думы?
короче говоря без Вансдорфа видимо не обойтись. и потоки никакие не помогут...
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373324
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,

и наш алгоритм это Backtracking . поиск с возвратом.
просто иная реализация. правда тут проще для восприятия.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373339
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81andron81,

и наш алгоритм это Backtracking . поиск с возвратом.
просто иная реализация. правда тут проще для восприятия.

То что я притащил в поиске, какой то злобно рекурсивный алгоритм, недалеко от brutal force ушел, тот же самый обход в лоб.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373491
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot andron81]uid uniqueпропущено...


с точки 0,0 (1,1) и у меня находит обычный обход доски неплохо обычным перебором. а вот с точки 1,0 и этот алгоритм уходит в думы? короче говоря без Вансдорфа видимо не обойтись. и потоки никакие не помогут...
Для рекурсии - это нормальное поведение. Свернул не в тот поворот - и дальше - семейство тупиков у которых path меньше
чем 64 - вот поэтому и долго работает.

А тренироваться на потоках на самом деле как раз удобно на таких алгоритмах. С год назад мы "тренировались"
на рисовании зеркальных шаров.... вот это эпично.

По поводу поиска в глубину. Я хотел проверить свои гипотезы.

1) Кластерный конь. Разбить доску на комнаты и определить жесткий порядок их обхода.
Например для доски 5х5 простой поиск находит решение быстро. Но мне нужно гарантировать
точки входа и выхода коня в строго нужной координате. Если нет - то попробовать 6х6.
После этого любые доски хоть 600х600 будут иметь решение за почти констатное время.

Для этого Варндсдорф не нужен. Тоесть может и нужен но он был-бы усложнением простой концепции.

2) Конь в лабиринте. Проверить возможно-ли обойти конём произольную форму доски (не прямоугольные
границы).

3) Конь-волновой. Проверить может-ли конь заливать пространство волной как в алгортме Мура.
(по сабжу я знаю что не может т.к. конь не ходит как ферзь или король но достигнуть локальной
близости) можно - попробовать.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373496
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Такая гипотеза.
В википедии написано, что существует 13 267 364 410 532 замкнутых и 19 591 828 170 979 904 незамкнутых решений данной задачи. Очевидно, что существует путь, начинающийся из любой выбранной точки - подойдет любое замкнутое решение. Но, возможно, для некоторых точек путь, который в них начинается, должен обязательно быть замкнутым (это и есть гипотеза). В этом случае поиск из такой точки будет в среднем в 1400 раз дольше. Это объясняет, почему у ТС из некоторых точек пути не находятся за разумное время, без применения некоторых оптимизирующих стратегий.
Ну и хотелось бы повозмущаться очередным копипастом в количестве 8 штук
Код: java
1.
2.
3.
4.
5.
		// go right and down
		if (canMove(row + 1, column + 2, N)
				&& findPath(row + 1, column + 2, index + 1, N)) {
			return true;
		}


Одни и те же действия с разными данными. Так и напрашивается массив с данными и итерация по нему
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373502
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По поводу Варндсдорфа. Наверное все уже прочилали вики. Так вот.
Там есть рисунок с ajcacency. Если-б я реализовывал Варнсдорфа - то
попробовал бы не расчитывать смежность а фиксировать при "установке"
коня или "снятии" (на обратном ходе).

Также есть мысль что для сегмента доски (2,2) - (n-2,n-2) возможно
свести работу с координатами к работе со смещениями в адресном
пространстве.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373506
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonПо поводу Варндсдорфа. Наверное все уже прочилали вики. Так вот.
Там есть рисунок с ajcacency. Если-б я реализовывал Варнсдорфа - то
попробовал бы не расчитывать смежность а фиксировать при "установке"
коня или "снятии" (на обратном ходе).

Также есть мысль что для сегмента доски (2,2) - (n-2,n-2) возможно
свести работу с координатами к работе со смещениями в адресном
пространстве.

не надо по поводу Вандерсофа с ним всё ясно, он работает...
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373518
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81не надо по поводу Вандерсофа с ним всё ясно, он работает...
Ты суть моего месседжа понял? О чем я вообще хотел сказать.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39373672
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonandron81не надо по поводу Вандерсофа с ним всё ясно, он работает...
Ты суть моего месседжа понял? О чем я вообще хотел сказать.

нет
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374208
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ладно. Я имел в виду не реализацию самого Варнсдорфа. Бох с ним. Я считаю что ты его уже
реализовал.

Я говорю о его дальнейшей оптимизации. Или о факте самой возможности. Если я не прав - что-ж.
Буду неправ. Но в графовых задачах (а это - типичная задача на поиск в графах) любая оптимизация
основана на том что мы икапсулируем в рёбра или вершины графа некую свою индексную информацию
при этом мы превносим некое вычислительное o(1) в сложность нашей формулы ... (а это говоря
простым языком - ништяк) но получаем взамен некие дополнительные поисковые возможности.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374226
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот в этой статье идея кластерного развита до обобщения в "Разделяй и властвуй".

http://larc.unt.edu/ian/pubs/algoknight.pdf

Хм... ну а на что я надеялся. Теорию обгрызли со всех сторон толпа математиков.
Остался пустяк. Имплементировать.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374233
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЯ говорю о его дальнейшей оптимизации. Или о факте самой возможности.
Можно сделать заготовки для обхода небольших по размеру досок и их комбинаций.
статья из науки и жизнь про подобное решение в досках ступенчатых квадратах
https://www.nkj.ru/archive/articles/11578/

Конь всегда ходит между клетками разного цвета; если представить себе отображение геометрии ходов коня в пешку в другой геометрии, то возможно это будет пешка на 4х мерной доске (8 вариантов хода, соседние клетки другого цвета). Доска будет 4х мерной (пространство ходов), конь пешкой. Интересно будет ли проще найти решение в 4х мерных шахматах с пешкой чем с конем в 2х мерных?
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374240
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
http://larc.unt.edu/ian/pubs/algoknight.pdf



классная инфа . судя по всему идёт речь о разбиении на более мелкие подполя (разделяй и властвуй)
я думал над этим . надо попробовать найти решения для доски 4x8 для начала. интересно есть такие ...
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374248
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid uniqueКонь всегда ходит между клетками разного цвета; если представить себе отображение геометрии ходов коня в пешку в другой геометрии, то возможно это будет пешка на 4х мерной доске (8 вариантов хода, соседние клетки другого цвета). Доска будет 4х мерной (пространство ходов), конь пешкой. Интересно будет ли проще найти решение в 4х мерных шахматах с пешкой чем с конем в 2х мерных?
Много-мерность в данной (прикладной) задаче не имеет никакого влияния на результат.
Это задача на маршруты в неориентированном графе. В теории. Как мы его представим -
в виде декартовых координат на плоскости или в гиперкубе - не имеет значения.

Разумеется мы можем графически их презнтовать так как нам удобно видеть.
На клеточной доске.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374273
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid unique, вот тоже самое решение я слегка переделал.

Changes:

Снял ограничения на квадратность доски. Теперь можно делать прямоугольники.

Добавил некую детерминированную шумящую функцию. Траектория коня будет зависеть от параметра randomSeed.

В чем у меня был баг? Проглядел что константа 0 используется как пометка пустой клетки. И у меня первый step
с уровнем 0 в рекурсии создал мне некие мелкие трудности.

TODO: desk[][] надо еще заменить на одномерный массив и где-то сбоку добавить базу готовых маршрутов
с проверками на уникальность и зеркальные отражения и развороты на 90 градусов.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
package mayton;

import java.util.Random;

import static java.lang.System.out;

public class MaytonsKnightTour {

    int[][] desk;

    int width;
    int height;

    int size;

    Random random;

    long randomSeed;

    public void cleanDesk(){
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                desk[i][j] = 0;
            }
        }
    }

    public MaytonsKnightTour(int height,int width) {
        this.width  = width;
        this.height = height;
        this.size = width * height;
        desk = new int[height][width];
        random = new Random();
    }

    public void solve(int i1,int j1,long randomSeed) {
        this.randomSeed = randomSeed;
        random.setSeed(randomSeed);
        cleanDesk();
        findPath(i1, j1, 1);
    }

    public boolean findPath(int i, int j, int level) {

        final int[] istep = {2, 1,-1,-2,-2,-1, 1, 2};
        final int[] jstep = {1, 2, 2, 1,-1,-2,-2,-1};


        if (desk[i][j] != 0) {
            return false;
        }

        desk[i][j] = level;

        if (level == size) {
            print();
            desk[i][j]=0;
            return true;
        }

        int rot = random.nextInt(8);

        for (int k = 0; k < 8; k++) {
            int krot = (k + rot) & 0x7;
            int iv = i + istep[krot];
            if (iv >= 0 && iv < height) {
                int jv = j + jstep[krot];
                if (jv >= 0 && jv < width) {
                    if (findPath(iv, jv, level + 1)) {
                        return true;
                    }
                }
            }
        }

        desk[i][j] = 0;
        return false;

    }

    public void print() {
        out.printf("\n== Solution with seed = %08Xh, size = (%d,%d) \n\n",randomSeed,height,width);
        String formatExpr = size < 100 ? "%02d " : "%03d ";
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                out.printf(formatExpr, desk[i][j]);
            }
            out.println();
        }
        out.printf("\n===============================\n");
    }

    public static void main(String[] args) {
        MaytonsKnightTour mkt = new MaytonsKnightTour(5,7);
        mkt.solve(0,0,0L);
        mkt.solve(0,0,1L);
        mkt.solve(0,0,2L);
    }

}



Stdout:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
== Solution with seed = 00000000h, size = (5,7) 

01 08 31 16 25 18 33 
30 05 24 09 32 15 26 
23 02 07 12 17 34 19 
06 29 04 21 10 27 14 
03 22 11 28 13 20 35 

===============================

== Solution with seed = 00000001h, size = (5,7) 

01 20 25 10 05 18 27 
24 11 22 19 26 31 06 
21 02 13 04 09 28 17 
12 23 34 15 30 07 32 
35 14 03 08 33 16 29 

===============================

== Solution with seed = 00000002h, size = (5,7) 

01 14 09 30 23 20 07 
10 29 22 03 08 31 24 
15 02 13 26 21 06 19 
28 11 34 17 04 25 32 
35 16 27 12 33 18 05 

===============================

Process finished with exit code 0
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374309
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonuid unique, вот тоже самое решение я слегка переделал.

Changes:

Снял ограничения на квадратность доски. Теперь можно делать прямоугольники.

Добавил некую детерминированную шумящую функцию. Траектория коня будет зависеть от параметра randomSeed.

В чем у меня был баг? Проглядел что константа 0 используется как пометка пустой клетки. И у меня первый step
с уровнем 0 в рекурсии создал мне некие мелкие трудности.

TODO: desk[][] надо еще заменить на одномерный массив и где-то сбоку добавить базу готовых маршрутов
с проверками на уникальность и зеркальные отражения и развороты на 90 градусов.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
package mayton;

import java.util.Random;

import static java.lang.System.out;

public class MaytonsKnightTour {

    int[][] desk;

    int width;
    int height;

    int size;

    Random random;

    long randomSeed;

    public void cleanDesk(){
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                desk[i][j] = 0;
            }
        }
    }

    public MaytonsKnightTour(int height,int width) {
        this.width  = width;
        this.height = height;
        this.size = width * height;
        desk = new int[height][width];
        random = new Random();
    }

    public void solve(int i1,int j1,long randomSeed) {
        this.randomSeed = randomSeed;
        random.setSeed(randomSeed);
        cleanDesk();
        findPath(i1, j1, 1);
    }

    public boolean findPath(int i, int j, int level) {

        final int[] istep = {2, 1,-1,-2,-2,-1, 1, 2};
        final int[] jstep = {1, 2, 2, 1,-1,-2,-2,-1};


        if (desk[i][j] != 0) {
            return false;
        }

        desk[i][j] = level;

        if (level == size) {
            print();
            desk[i][j]=0;
            return true;
        }

        int rot = random.nextInt(8);

        for (int k = 0; k < 8; k++) {
            int krot = (k + rot) & 0x7;
            int iv = i + istep[krot];
            if (iv >= 0 && iv < height) {
                int jv = j + jstep[krot];
                if (jv >= 0 && jv < width) {
                    if (findPath(iv, jv, level + 1)) {
                        return true;
                    }
                }
            }
        }

        desk[i][j] = 0;
        return false;

    }

    public void print() {
        out.printf("\n== Solution with seed = %08Xh, size = (%d,%d) \n\n",randomSeed,height,width);
        String formatExpr = size < 100 ? "%02d " : "%03d ";
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                out.printf(formatExpr, desk[i][j]);
            }
            out.println();
        }
        out.printf("\n===============================\n");
    }

    public static void main(String[] args) {
        MaytonsKnightTour mkt = new MaytonsKnightTour(5,7);
        mkt.solve(0,0,0L);
        mkt.solve(0,0,1L);
        mkt.solve(0,0,2L);
    }

}



Stdout:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
== Solution with seed = 00000000h, size = (5,7) 

01 08 31 16 25 18 33 
30 05 24 09 32 15 26 
23 02 07 12 17 34 19 
06 29 04 21 10 27 14 
03 22 11 28 13 20 35 

===============================

== Solution with seed = 00000001h, size = (5,7) 

01 20 25 10 05 18 27 
24 11 22 19 26 31 06 
21 02 13 04 09 28 17 
12 23 34 15 30 07 32 
35 14 03 08 33 16 29 

===============================

== Solution with seed = 00000002h, size = (5,7) 

01 14 09 30 23 20 07 
10 29 22 03 08 31 24 
15 02 13 26 21 06 19 
28 11 34 17 04 25 32 
35 16 27 12 33 18 05 

===============================

Process finished with exit code 0





ай, вот не в ту стороную вы. реализация может и отлична от моей , но вот решения для 8x8 , со старта 0,0 у меня терпения дождаться не выходит.

Вы бы лучше бы наривали как в потоках это всё бы выглядело , раз не лень писать код.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374322
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81Вы бы лучше бы наривали как в потоках это всё бы выглядело , раз не лень писать код.
В этой реализации простая рекурсия, если смысл в потоках?
в потоках будете шарить доску int[][] desk; вот этот код можете запустить в 8 потоках вместо цикла но в лоб с этой рекурсией хорошо не получится

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
for (int k = 0; k < 8; k++) {
     // Thead (k) task
            int krot = (k + rot) & 0x7;
            int iv = i + istep[krot];
            if (iv >= 0 && iv < height) {
                int jv = j + jstep[krot];
                if (jv >= 0 && jv < width) {
                    if (findPath(iv, jv, level + 1)) {
                        return true;
                    }
                }
            }
        }



Нужно сделать более мелкие задания для потоков с примерно одинаковым временем выполнения и разделить код на management (управляющая логика, обходчик) и worker (исполнители в потоках). Исполнители возвращают результат работы и контекст их задания (переменные состояния), затем делается новое задание и отдается в свободный поток (в пул).
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374323
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81ай, вот не в ту стороную вы. реализация может и отлична от моей , но вот решения для 8x8 , со старта 0,0 у меня терпения дождаться не выходит.

Вы бы лучше бы наривали как в потоках это всё бы выглядело , раз не лень писать код.
Давай порассуждаем. Если стоит задача быстро найти 1-е решение то Варнсдорф рулит.
А если нужно найти все решения? Будет ли он столь-же эффективен как и Deep-First-Search (DFS) ?
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374324
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid unique в потоках будете шарить доску int[][] desk; вот этот код можете запустить в 8 потоках вместо цикла но в лоб с этой рекурсией хорошо не получится
Ууид! Ну это фейспалм какой-то. Я-же говорю. Не надо шарить доску! Вообще ни разу не надо!
Каждому потоку - дана своя доска!
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374325
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Deep-First-Search (DFS) ?



что значит first в этом словосочетании ?
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374326
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DFS это один из вариантов англоязычного названия метода. Ему противостоит Breadth-first search.
Типа поиск в ширину. Но в данном переводе насколько я понимаю first означает "в первую очередь".
Тоесть в первую очередь исследовать глубину. А альтернативный алгоритм - делает акцент на ширину.
Например заливка краской пикселей - это обычно поиск в ширину.

Сорян за мой английский. Где-то я мог и ошибаться в нюансах.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374327
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

понятно . DFS короче это поиск в глубину .
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374331
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Давай порассуждаем. Если стоит задача быстро найти 1-е решение то Варнсдорф рулит.
А если нужно найти все решения? Будет ли он столь-же эффективен как и Deep-First-Search (DFS) ?



Сомневаюсь в вашей гипотезе .
как я понимаю , Варнсдорф в худшем случае (для очень больших шахматных досок) превращается в обычный поиск в глубину хоть ветки и берутся не последовательно и не рандомно, а по правилу наименьшего исхода из них (веток). мы же в случае тупика вернёмся и просто выкидываем из рассмотрения тупиковую ветку и возьмем опять наименьшую . (я так делал)
мне кажется , что Варнсдорф это просто подсказка к глубинному методу
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374333
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81Сомневаюсь в вашей гипотезе .
как я понимаю , Варнсдорф в худшем случае (для очень больших шахматных досок) превращается в обычный поиск в глубину хоть ветки и берутся не последовательно и не рандомно, а по правилу наименьшего исхода из них (веток). мы же в случае тупика вернёмся и просто выкидываем из рассмотрения тупиковую ветку и возьмем опять наименьшую . (я так делал)
мне кажется , что Варнсдорф это просто подсказка к глубинному методу
Да. Но Варнсдорф за это платит свою цену. Он обозревает узлы еще на шаг вперед а для простого
получения ВСЕХ решений это избыточные расчеты.

Впрочем я не настаиваю.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374432
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton Не надо шарить доску! Вообще ни разу не надо!
Каждому потоку - дана своя доска!
Если у каждого потока своя доска то либо у каждого потока свой алгоритм (обход) не пересекающийся с другими потоками либо обмен данными (какими?). Потоки обходят одну доску, это общий ресурс, как делается разделение ресурса?
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374436
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще раз читаем внимательно условие.

Требуется реализовать задачу обхода шахматного коня всей шахматной доски 8x8 из клетки (i,j) так, чтобы в каждой клетке он(конь) побывал ровно по одному разу.
Способ реализации мультипоточный 4 - потока = const (можно и больше, не принципиально, лишь бы найти решение(я)). алгоритм - методом обхода в глубину .
Исходные данные:
4 (или более) потока(константа) - задано жестко в программе.
M - минимальное число маршрутов коня которые нужно найти.
i,j - стартовая точка.
M,i,j - задаются в виде аргументов командной строки.

Я беру на себя смелость добавить еще одно дополнение к условию. На основании того как я понял дизайн
вывода результата.

Маршруты коня должны быть уникальны. Маршруты которые
являются зеркальными отражениями друг друга или копиями с разворотом доски в 90 градусов
также считаются дублями. Их выдавать в ответ не нужно.

Далее я рассуждаю.

У нас - идеальная задача для параллелизма. Каждый поток получает задачу - стартовую точку.
И фактически коллизия потоков возникает только в самом конце (когда идет проверка что маршрут
является дублем) и это и будет точка конкуренции.

Я предполагаю что она будет занимать менее 1% общего времени выполнения работы приложения
и это не оказывает влияния на время поиска M маршрутов.

Шарить доски нет никакого смысла т.к. они являются ГОРЯЧИМ ресурсом и постоянно находятся
под нагрузкой. Любая попытка их росшарить приведет к провальному понижению КПД работы
потоков. Впрочем последнее - это моё эвристическое предположение и вы можете его проверить
и опровергнуть. Всё также будет зависеть от реализации.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374437
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid uniqueЕсли у каждого потока своя доска то либо у каждого потока свой алгоритм (обход)

да . я предполагал и делал так : у них просто рандомно выбираются ветки. может где-то и пересекутся разок, но дальше вряд ли...
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374543
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81uid uniqueЕсли у каждого потока своя доска то либо у каждого потока свой алгоритм (обход)

да . я предполагал и делал так : у них просто рандомно выбираются ветки. может где-то и пересекутся разок, но дальше вряд ли...
условие невнимательно посмотрел, спасибо, оказывается задача проще чем казалось - нужно 4 различных решения а не одно ускорить в 4х потоках. У меня мысль свернула на ускорение поиска одного решения, доска тогда шарится, задачи для потоков нужно нарезать по хитрому, не слишком маленькие или большие.

Вместо рандомного индекса можно сделать сдвиг и направление обхода массива шагов в зависимости от индекса потока, они пойдут по разным маршрутам и это намного быстрее рандома.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374555
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DFS в 4 потока. Как-то так вобщем. По поводу executorService. Я не уверен что 100% корректно его
использую. Редко юзал. Возможно там есть нюансы с очередью и финализацией. Вобщем как-то так.

По поводу недостатков Варнсдорфа. Они все такие есть. Но воспроизводятся на больших M. Чуть позже
я попробую обосновать.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
package mayton;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.io.PrintStream;
import java.util.Random;
import java.util.concurrent.*;

import static java.lang.Long.numberOfLeadingZeros;
import static java.lang.System.out;
import static java.util.Arrays.fill;

public class MaytonsKnightTour {

    static final int KNIGHT_DIRECTIONS = 8;

    int i1;
    int j1;

    int[] desk;

    int width;
    int extendedWidth;
    int ws;
    int height;

    int size;

    Random random;

    long randomSeed;

    public void cleanDesk(){
        fill(desk,0);
    }

    public MaytonsKnightTour(int height,int width,int i1,int j1,long randomSeed) {
        this.width  = width;
        this.height = height;
        this.extendedWidth = Utuls.clp2(width);
        this.ws = Utuls.log2up(width);
        this.size = width * height;
        this.i1 = i1;
        this.j1 = j1;
        this.randomSeed = randomSeed;
        desk = new int[height * extendedWidth];
        random = new Random();
    }

    public void solve(){
        cleanDesk();
        findPath(i1, j1, 1);
    }

    public void solve(int i1,int j1,long randomSeed) {
        this.randomSeed = randomSeed;
        random.setSeed(randomSeed);
        cleanDesk();
        findPath(i1, j1, 1);
    }

    public boolean findPath(int i, int j, int level) {

        final int[] istep = {2, 1,-1,-2,-2,-1, 1, 2};
        final int[] jstep = {1, 2, 2, 1,-1,-2,-2,-1};

        int offset = (i<< ws) + j;

        if (desk[offset] != 0) {
            return false;
        }

        desk[offset] = level;

        if (level == size) {
            print(System.out);
            desk[offset]=0;
            return true;
        }

        int rot = random.nextInt(KNIGHT_DIRECTIONS);

        for (int k = 0; k < KNIGHT_DIRECTIONS; k++) {
            int krot = (k + rot) & 0x7;
            int iv = i + istep[krot];
            if (iv >= 0 && iv < height) {
                int jv = j + jstep[krot];
                if (jv >= 0 && jv < width) {
                    if (findPath(iv, jv, level + 1)) {
                        return true;
                    }
                }
            }
        }

        desk[offset] = 0;
        return false;

    }

    public void print(PrintStream out) {
        synchronized (out) {
            out.printf("\n== Solution with seed = %08Xh, size = (%d,%d) \n\n", randomSeed, height, width);
            String formatExpr = size < 100 ? "%02d " : "%03d ";
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    out.printf(formatExpr, desk[(i << ws) + j]);
                }
                out.println();
            }
            out.printf("\n===============================\n");
        }
    }

    public static void main(String[] args) {

        final int THREADS = 4;
        final int M = 100; // Integer.valueOf(args[0]);

        ThreadFactory knightTourThreadFactory = new ThreadFactoryBuilder()
                .setNameFormat("Knight-Tour-Thread-%d")
                .setDaemon(false)
                .build();

        ExecutorService executor = Executors.newFixedThreadPool(THREADS, knightTourThreadFactory);

        try {
            for (int i = 0; i < M; i++) {
                executor.execute(new MaytonsKnightTourThread(
                        new MaytonsKnightTour(5, 7, 0, 0, (long)i))); // 8x8 - Too slow...
            }
        } finally {
            executor.shutdown();
        }
    }

}

...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374558
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По поводу 8х8. DFS - тормоз ясен пень. На данной конкретной постановке когда мы хотим очень
быстро получить 1-й солюшен и отвалить. Но Варнсдорф мне почему-то напомнил старый добрый
алгоритм мыши в лабиринте которая бегает касаясь левой (или правой ) стены и постоянно сворачивает
в одну сторону.

Вобщем у этого метода есть недостатки. В частности если посмотреть на блуждания лошади с
на большом поле (порядка 130 на 130) с высоты птичьего полета то можно видеть что
конь ходит подобно этой мыши которую я описал. Тоесть прижимается к своей собственной
тропинке которую уже проходил.



Я считаю это если не фейком то просто увеличением энтропии самого маршрута. А именно -
маршрут предстказуем и ограничен. Что будет после того как все "мышиные" маршруты
закончятся и начнётся хардкор, по которому ходит "честный DFS" - я не знаю.

Скорее всего правило Варнсдорфа будет реже выдавать результаты именно в силу того
что наиболее популярный мышиные уже исследованы. А реже - имеено по причине наличия
эвристики.

По сабжу тот DFS что я скопи-пастил и переделал тоже имеет недостатки. В частности
мне очень не нравится что он каждый раз начинает маршрут заново. Хотелось-бы
идти от изменений существующего. Но это уже без Random. А как-то по другому.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374603
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton Хотелось-бы
идти от изменений существующего. Но это уже без Random. А как-то по другому.
Можно сворачивать в сторону где меньше натоптано (и наоборот).
Деление доски на части и обход частей уже смотрели https://pdfs.semanticscholar.org/927e/dbaa256301f500e8b3fcd52eaa6f0cc2c768.pdf
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374613
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid uniquemayton Хотелось-бы
идти от изменений существующего. Но это уже без Random. А как-то по другому.
Можно сворачивать в сторону где меньше натоптано (и наоборот).
Деление доски на части и обход частей уже смотрели https://pdfs.semanticscholar.org/927e/dbaa256301f500e8b3fcd52eaa6f0cc2c768.pdf
Что значит - "можно" ? Я и сам знаю что можно. Предложите ваш код.

Деление смотрел. Если мы решили задачу обхода 5х5 и при этом (!) гарантируем
что для любого блока 5x5 можем заставить коня войти и выйти в нужную дверь
(вход-выход) то задача обхода 130 на 130 уже решена за o(n).

Но мне решать такие задачи не очень-то интересно. Формально доказать
что вход-выход в 5х5 существует. Или 5х10.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374615
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да. Я не весь сорс опубликовал. Есть еще мелкая либа. Более полный вариант проекта здесь

https://sourceforge.net/p/chess-experiments/code/HEAD/tree/trunk/mayton/knight-tour/
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374686
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЧто значит - "можно" ? Я и сам знаю что можно. Предложите ваш код.

Только когда уйду в отпуск ;-) стараюсь хотя бы на выходных код не писать а в прошлые выходные работал.
так что пока спрыгиваю с темы но буду подумывать на досуге, может что и придет в голову.

Если ускорять бэкрейсинг то можно использовать просчитанные матрицы ходов к примеру для досок 5х5 (их около 2 тыс) и проверять текущую позицию через поиск подходящей матриц(ы) 5х5 (или меньшей в зависимости от позиции), здесь бы отлично подошла CAM память (проверка за один такт всех матриц 5х5). Ускорили бы бэктрейсинг примерно в 50 тыс раз (25 х 2000).
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374697
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid uniqueТолько когда уйду в отпуск ;-) стараюсь хотя бы на выходных код не писать а в прошлые выходные работал.
так что пока спрыгиваю с темы но буду подумывать на досуге, может что и придет в голову.

Да ради бога. Я никуда не тороплю.

Если ускорять бэкрейсинг то можно использовать просчитанные матрицы ходов к примеру для досок 5х5 (их около 2 тыс) и проверять текущую позицию через поиск подходящей матриц(ы) 5х5 (или меньшей в зависимости от позиции), здесь бы отлично подошла CAM память (проверка за один такт всех матриц 5х5). Ускорили бы бэктрейсинг примерно в 50 тыс раз (25 х 2000).
Чо? Какая такая CAM-память? Ассоциативная? Не понял зачем это надо. Когда у нас есть бесконечное
разнообразие hashtable/hashmap. И узкое место в - рекурсии а имеенно в движении коня по 8 направлениям
а вовсе не в маппингах.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374709
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Немножко переделал параметры. Не нравятся константы вбитые в код. Особенно в части 4 threads.
Теперь так:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
 if (args.length==0){
            out.printf("\nRandom DFS knight-tour problem demo. Shows first M knight paths.");
            out.printf("\n\nUsage: java -jar knight-tour-X.X.jar WIDTH HEIGHT M THREADS [R1 C1]\n");
            out.printf("\n  Where:\n");
            out.printf("       WIDTH   : width of desk (number)\n");
            out.printf("       HEIGHT  : height of desk (number)\n");
            out.printf("       M       : amout of solutions wich has to be found (number)\n");
            out.printf("       THREADS : number of JVM-worker threads (number)\n");
            out.printf("       R1      : (optional) first position row (number)\n");
            out.printf("       C1      : (optional) first position column (number)\n");
        } else {
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374714
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не знаю как насчет эффективности, а утилизацию обеспечивает.
Вот так картинка выглядит с точки зрения JVisualVM при THREADS=5 (На моем ноуте - оптимально 5 threads).
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374739
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По поводу моей идеи кластерного коня, которая впрочем обсуждалась в литературе.
Экспериментально я нашел что минимальная доска на которую можно покрыть конем
это 4х5 или 5х4.

Осталось еще доказать что всегда сущесвуют маршруты с нужной точкой входа и выхода.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374817
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonПо поводу моей идеи кластерного коня, которая впрочем обсуждалась в литературе.
Экспериментально я нашел что минимальная доска на которую можно покрыть конем
это 4х5 или 5х4.

Осталось еще доказать что всегда сущесвуют маршруты с нужной точкой входа и выхода.
Это алгоритм Конрада
http://mathworld.wolfram.com/KnightGraph.html

Conrad et al. (1994) discovered another linear time algorithm and proved that it solves the Hamiltonian path problem for all n>=5. The Conrad et al. algorithm works by decomposition of the chessboard into smaller chessboards (not necessarily square) for which explicit solutions are known. This algorithm is rather complicated because it has to deal with many special cases, but has been implemented in the Wolfram Language by A. Roth. Example tours are illustrated above for n×n boards with n=5 to 8.

По поводу CAM памяти идея была в использовании при сравнении части доски с просчитанными матрицами за один такт и нахождении пересечений деревьев (маршрутов). Сразу накладывать ходы на глубину в 2-3 шага в виде штампа (без самопересечений) и обрабатывать только те которые не имеют пересечений с доской (листьев будет не так много, больше 8 но и не тысячи).
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374859
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Конрад пошел еще дальше чем Варнсдорф. По сути задача решается выкладыванием
мозаики из готовых шаблонов.

Но все эти алгоритмы играют на строго прямоугольных досках. Что будет если им подать
на вход доску с отверстием. Или доску неправильной формы.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374887
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonКонрад пошел еще дальше чем Варнсдорф. По сути задача решается выкладыванием
мозаики из готовых шаблонов.

Но все эти алгоритмы играют на строго прямоугольных досках. Что будет если им подать
на вход доску с отверстием. Или доску неправильной формы.

Да, это очень ограниченые методики, полных решений для доски 8х8 неизвестное количество, есть только грубая оценка.
На ночь глядя склепал небольшой пример (не компилировал) для пояснения как можно использовать САМ с кешем для бэкрейсинга или рекурсивного обхода доски.

Используются заранее расчитанные варианты шагов фиксированной глубины (положим 4, получается не такое большое количество вариантов максимум 8 * 7 * 7 * 7 = 2744 и дерево с 16 уровнями вместо 63.
1. Хранятся в бинарном виде позиции для каждого возможного пути глубиной N из заданой точки на доске (64 bit, long value)
2. По бинарному пути точек хранится траектория движения.
3. Вместо последовательного сравнения можно использовать CAM память и получить за 1 такт выборку возможных путей. Для глубины в 8 шагов экономия будет существенной (6.5 млн раз) a а размер кеша терпимым (420МБ для бинарного массива и 2 3 гига для объектов, можно уменьшить).

С САМ возможно ускорение примерно на 6 порядков. Завтра вставать в 5, ушел...
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
package knight;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

public class PrecalculatedPaths {
    private static final Logger logger = LoggerFactory.getLogger(PrecalculatedPaths.class);

    static final int [] STEP_DELTA_X = {1, 2, 2, 1, -1, -2, -2, -1};
    static final int [] STEP_DELTA_Y = {2, 1, -1, -2, -2, -1, 1, 2};

    static final int BOARD_WIDHT = 8;
    static final int BOARD_HEIGHT = 8;
    static final int DEPTH = 4;

    // first index: position on chess board (index = x * BOARD_WIDHT + y)
    // second index: array of paths from each position (first index) in binary format
    // bit at position boardWidth * BOARD_HEIGHT - 1 (63) represents state of cell x=0, y=0 and equals 1 if cell is used and 0 otherwise;
    // bit at position boardWidth * BOARD_HEIGHT - 2 (62) represents cell x=1, y=0

    static final long[][] POSSIBLE_STEP_POSITIONS;
    static final Map<Long, List<Position>> PATH_BY_BINARY_POS;


    static {
        logger.info("Building static paths");

        POSSIBLE_STEP_POSITIONS = new long[BOARD_HEIGHT * BOARD_WIDHT][];
        PATH_BY_BINARY_POS = new HashMap<>();

        long positionsInBinaryFormat;

        for(int x = 0; x < BOARD_WIDHT; x++ ) {
            for(int y = 0; y < BOARD_HEIGHT; y++) {

                List<List<Position>> paths = explore(x, y, DEPTH);

                int pathCount = paths.size();
                POSSIBLE_STEP_POSITIONS[x * BOARD_WIDHT + y] = new long[pathCount];

                for(int i = 0; i < pathCount; i++) {
                    //Compact to binary format
                    List<Position> path = paths.get(i);
                    positionsInBinaryFormat = toBinaryPositions(path);

                    POSSIBLE_STEP_POSITIONS[x * BOARD_WIDHT + y][i] = positionsInBinaryFormat;

                    PATH_BY_BINARY_POS.put(positionsInBinaryFormat, path);
                }
            }
        }
    }


    /**
     * Get pre-calculated paths DEPTH deep for position on the board x, y and
     * current board state (board[][] contains cells states: 1 when cell is used and 0 when it is free)
     *
     * @param xPos x position on the board
     * @param yPos y position on the board
     * @param board chess board cells state (0 is free, 1 is used)
     * @return
     */
    public List<List<Position>> getPrecalculatedPaths(int xPos, int yPos, int[][] board) {
        List<List<Position>> validPaths = null;

        long boardState = 0L;

        //Create board state in binary format (or use binary format in input parameters)
        for(int x = 0; x < board.length; x++) {
            for(int y = 0; y < board[x].length; y++) {
                if(board[x][y] == 1) {
                    boardState = boardState & (1 << boardPositionToBinaryShift(x, y));
                }
            }
        }

        int flatIndex = boardPositionToBinaryShift(xPos, yPos);

        long[] paths = POSSIBLE_STEP_POSITIONS[flatIndex];

        //CAM can be used here to skip loop
        for(int i = 0; i < paths.length; i++) {
             if((paths[i] & boardState) == 0L) {
                 //If no intersections found, add path as valid
                 if(validPaths == null) {
                     validPaths = new ArrayList<>();
                 }

                 validPaths.add(PATH_BY_BINARY_POS.get(paths[i]));
             }
         }


        return validPaths;
    }

    private static long toBinaryPositions(List<Position> path) {
        long binaryPositions = 0L;

        for(Position position : path) {
            binaryPositions = binaryPositions & (1 << boardPositionToBinaryShift(position.x, position.y));
        }

        return binaryPositions;
    }

    private static int boardPositionToBinaryShift(int x, int y) {
        return x * BOARD_WIDHT + y;
    }

    private static List<List<Position>> explore(int x, int y, int maxSteps) {

        List<Position> startPath =  new ArrayList<>();
        startPath.add(new Position(x, y));

        List<List<Position>> possiblePaths =  new ArrayList<>();
        possiblePaths.add(startPath);

        for(int i = 0; i < maxSteps; i++) {
            possiblePaths = exploreLevel(possiblePaths);
        }

        return possiblePaths;
    }

    private static List<List<Position>> exploreLevel(List<List<Position>> parentPaths) {
        List<List<Position>> levelPaths =  new ArrayList<>();

        for(List<Position> parentPath : parentPaths) {
            List<List<Position>> childrenPaths =  new ArrayList<>();
            Position parentPos = parentPath.get(parentPath.size() - 1);
            HashSet<Position> usedPositions = new HashSet<>(parentPath);

            for (int i = 0; i < 8; i++) {
                Position candidate = new Position(parentPos.x + STEP_DELTA_X[i], parentPos.y + STEP_DELTA_Y[i]);

                if (usedPositions.contains(candidate) || (candidate.x < 0 || candidate.x > 7) || (candidate.y < 0 || candidate.y > 7)) {
                    continue;
                }

                List<Position> levelPath = new ArrayList<>();
                Collections.copy(levelPath, parentPath);

                levelPath.add(candidate);

                childrenPaths.add(levelPath);
            }

            //If nothing found, return input
            if (childrenPaths.isEmpty()) {
                childrenPaths.add(parentPath);
            }

            levelPaths.addAll(childrenPaths);
        }

        return levelPaths;
    }


}
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39374944
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid unique, ничо непонятно. Где entry-point? Как это использовать?

Хотя-б модульный тест был-бы.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39375888
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonuid unique, ничо непонятно. Где entry-point? Как это использовать?

Хотя-б модульный тест был-бы.
Пардон, это всего лишь иллюстрация использования САМ и кеша заранее рассчитанных ходов из любой позиции на доске.
Даже без ассоциативной памяти с кешем бэкрейс будет работать шустрее. Написано грубовато, на ночь глядя, без проверок.

Entry point:
public List<List<Position>> getPrecalculatedPaths(int xPos, int yPos, int[][] board)

Метод thread safe, доступ только на чтение из потоков.

даете массив позиций на доске (0 ячейка свободна, 1 занята) и получаете коллекцию ходов коня на 4 шага вперед не конфликтующую с позициями на доске.Можете использовать тот же бэктрейсинг но не с 64 уровнями а с 16.

В бэктрейс несколько потоков молотят один и тот же цикл проверки ходов коня для каждой ячейки на доске, одинаковая работа делается несколько раз, сравнение тоже в цикле идет. В кеше хранятся позиции коня для ходов на глубину в 4 шага (можно менять глубину) и сравнение делается по бинарным полям в long массива позиций фигур на доске в биты в long (как в массиве). Так как упаковка позиций в 64 бита переменную то макс площадь доски не более 64 позиций.

А вот если бы была САМ память то вместо цикла получили бы выполнение сравнения за один такт. Здесь даже не true CAM подошла бы а гибридный вариант с сегментами обычной памяти (примерно как хэшмапа в Java устроена сначала быстрый поиск по хэш коду а потом в листе).
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39375894
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid uniqueА вот если бы была САМ память то вместо цикла получили бы выполнение сравнения за один такт. Здесь даже не true CAM подошла бы а гибридный вариант с сегментами обычной памяти (примерно как хэшмапа в Java устроена сначала быстрый поиск по хэш коду а потом в листе).

Облизываюсь на продукцию вот этой конторы давненько уже (лет 10) https://www.opalkelly.com/products/
Может все таки возьму эту плату или подобную в хозяйство https://www.opalkelly.com/products/xem7360/
стряхну пыль с книжек по Verilog и VHDL (лежат на полочке уже давно), скачаю новые версии IDE и тогда можно будет поизвращаться с шахматными задачками и специализированными ускорителями. Типовая бизнес Java действует на меня отупляюще, перестал думал, скоро буду мычать как Маугли ;-)
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39378533
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Докину дровишек.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39378535
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid uniqueПардон, это всего лишь иллюстрация использования САМ и кеша заранее рассчитанных ходов из любой позиции на доске.
Даже без ассоциативной памяти с кешем бэкрейс будет работать шустрее. Написано грубовато, на ночь глядя, без проверок.

Entry point:
public List<List<Position>> getPrecalculatedPaths(int xPos, int yPos, int[][] board)

Метод thread safe, доступ только на чтение из потоков.

даете массив позиций на доске (0 ячейка свободна, 1 занята) и получаете коллекцию ходов коня на 4 шага вперед не конфликтующую с позициями на доске.Можете использовать тот же бэктрейсинг но не с 64 уровнями а с 16.

В бэктрейс несколько потоков молотят один и тот же цикл проверки ходов коня для каждой ячейки на доске, одинаковая работа делается несколько раз, сравнение тоже в цикле идет. В кеше хранятся позиции коня для ходов на глубину в 4 шага (можно менять глубину) и сравнение делается по бинарным полям в long массива позиций фигур на доске в биты в long (как в массиве). Так как упаковка позиций в 64 бита переменную то макс площадь доски не более 64 позиций.

А вот если бы была САМ память то вместо цикла получили бы выполнение сравнения за один такт. Здесь даже не true CAM подошла бы а гибридный вариант с сегментами обычной памяти (примерно как хэшмапа в Java устроена сначала быстрый поиск по хэш коду а потом в листе).
Я тут пожалуй хочу услышать каменты коллег. Я мало чего понял.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39378672
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЯ тут пожалуй хочу услышать каменты коллег. Я мало чего понял.
Мэйтон, с Новым Годом! У меня все болеют вокруг, один я еще пока держусь (как в фильмах про зомби), открыл бутылочку Камю, хряпнул соточку неторопясь закусывая вкусной конфеткой... хороший коньячок в ЦУМе продают, не ожидал. Хорошо москвичи живут, в провинции такой коньяк найти трудно.
В общем о чем я - с наилучшими пожеланиями в Новом 2017 году, чтоб были идеи в голове, интересная работа, здоровья хватало и семья была в порядке (жена довольна)! Чтоб наши потребности не опережали наши возможности и было счастье и лепота на душе!

PS по поводу промера кода, ну что там непонятного? наспех написанный примерчик, набросок. Вместо проверки на один шаг делается проверку сразу на 4 шага вперед (количество шагов произвольное число, зависит от доступного размера кеша), у САМ памяти преимущество в том что поиск в несортированном массиве (любого размера) делается за 1 такт. Причем поиск может идти по маске а не полному совпадению.
PSS Когда эта память станет массовой она перевернет устоявшиеся подходы в решении задач и многие неэффективные раньше алгоритмы получат второе дыхание.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39378959
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonДокину дровишек.

это ваша реализация отработала ?
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39378961
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да. Та которую я опубликовал по ссылке выше.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39378964
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
друзья , напоминаю вам , что вопрос был относительно потоков. Доска 8x8 . поэтому никаких прямоугольных досок, никаких "дырок" в доске.
старт осуществляем из клетки указанный пользователем.
Рассуждения по поводу Варнсдорфа не интересны.

Интересовал собственно вопрос возможно ли реализовать вывод хотя бы одного решения при помощи 4-х потоков или более.
Да / Нет.

Спасибо.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39378967
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да.
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39378984
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonДа.
нет возможности пока скачать и посмотреть
а с любой точки искалос? скажем с точки 0:1 , или 0:2
у меня с них висло все
...
Рейтинг: 0 / 0
задача конем шахматной доски.
    #39379027
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для DFS - нормально работает для размеров до 7х7. Правда нет в моей реализации команды stop
после первого найденного и пока 4 потока не отработают - процесс продолжает активность.
Впрочем такой задачи я себе не ставил.

Для DFS я пока не дождался решения 8х8. Мне жалко мой ноутбук Core-i3. Да батарея выгорает
быстро когда он под нагрузкой.

Но думаю завтра-послезавтра я доделаю Варнсдорфа и тоже добавлю его в список алгоритмов как
плагин. И если у меня хватит сил - UI c графиками и статистикой.

Есть еще несколько мыслей. Надо попробовать доску-тор. И доску-лабиринт где будут стоять
другие фигуры. Чтоб не было явного преимущества у "беготни вдоль забора".
...
Рейтинг: 0 / 0
74 сообщений из 74, показаны все 3 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / задача конем шахматной доски.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]