powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / задача конем шахматной доски.
25 сообщений из 74, страница 2 из 3
задача конем шахматной доски.
    #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
25 сообщений из 74, страница 2 из 3
Форумы / Java [игнор отключен] [закрыт для гостей] / задача конем шахматной доски.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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