8 / 8 / 12
Регистрация: 16.05.2014
Сообщений: 151
1

Реализация обучения с подкреплением

04.11.2018, 17:11. Показов 3526. Ответов 0
Метки нет (Все метки)

Здравствуйте. Изучаю сейчас тему обучения с подкреплением на примере игры в крестики-нолики. Вроде бы сделал, но по моему криво работает, можете подсказать сделал ли я что то не правильно?

Собственно алгоритм:
Кликните здесь для просмотра всего текста

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
public class ReinforcementTraining {
    private DbHandler local;
    private GameState oldState = null;
 
    private static final double ALPHA = 0.125;
 
    public ReinforcementTraining() {
        try {
            local = DbHandler.getInstance();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
 
    public String findBestMove(String s){
        double bestVal = -1000;
        List<GameState> bestMoves = new ArrayList<>();
 
        long count = s.chars().filter(value -> value == ' ').count();
 
        if((int)(Math.random() * 100) < 30){
            int rand = 1 + (int)(Math.random() * count);
            String str = makeString(s, rand, "x");
            double value = evaluation2(str);
 
            oldState = new GameState(str, value);
            if(local.get(str) == null){
                local.add(new GameState(str, value));
            }
 
            return str;
        }
 
 
        for(int i=1; i<=count; i++){
            String str = makeString(s, i, "x");
 
            double x = evaluation2(str);
 
            if(x >= bestVal){
                bestVal = x;
 
                if(!bestMoves.isEmpty()){
                    if(bestMoves.get(0).getValue() < bestVal){
                        bestMoves.clear();
                    }
                }
                bestMoves.add(new GameState(str, bestVal));
            }
        }
 
        String resultMove = bestMoves.get((int)(Math.random()*bestMoves.size()-1)).getState();
 
        correct(bestVal);
        oldState = new GameState(resultMove, bestVal);
 
        return resultMove;
    }
 
    public void remember(String state, boolean isWin){
        double value = (isWin?1:-1) * 10;
        correct(value);
        updateState(state, value);
    }
 
    private void updateState(String state, double value){
        if(local.get(state) != null){
            local.update(state, new GameState(state, value));
        }else{
            local.add(new GameState(state, value));
        }
    }
 
    private double evaluation2(String s){
        char[] arr = s.toCharArray();
 
        //rows
        for(int i=0; i<3; i++){
            if(arr[3*i] == 'x' && arr[3*i+1] == 'x' && arr[3*i+2] == 'x'){
                return 10;
            }else if(arr[3*i] == 'o' && arr[3*i+1] == 'o' && arr[3*i+2] == 'o'){
                return -10;
            }
        }
 
        //columns
        for(int i=0; i<3; i++){
            if(arr[i] == 'x' && arr[3+i] == 'x' && arr[6+i] == 'x'){
                return 10;
            }else if(arr[i] == 'o' && arr[3+i] == 'o' && arr[6+i] == 'o'){
                return -10;
            }
        }
 
        //diagonals
        if(arr[0] == 'x' && arr[1*3+1] == 'x' && arr[2*3+2] == 'x'){
            return 10;
        }else if(arr[0] == 'o' && arr[1*3+1] == 'o' && arr[2*3+2] == 'o'){
            return -10;
        }
 
        if(arr[2] == 'x' && arr[4] == 'x' && arr[6] == 'x'){
            return 10;
        }else if(arr[2] == 'o' && arr[4] == 'o' && arr[6] == 'o'){
            return -10;
        }
 
        GameState state = local.get(s);
        if(state != null){
            return state.getValue();
        }
 
        return 0;
    }
    
    private void correct(double value){
        if(oldState == null){
            return;
        }
 
        double newVal = oldState.getValue() + ALPHA*(value - oldState.getValue());
        updateState(oldState.getState(), newVal);
    }
 
    private String makeString(String current, int index, String player) {
        String res = current;
 
        for (int i=0; i<index; i++) {
            res = res.substring(res.indexOf(" ") + 1);
        }
        res = player + res;
 
        return current.substring(0, current.length() - res.length()) + res;
    }
}


Отрисовка поля и игровой цикл:
Кликните здесь для просмотра всего текста

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
public class Board {
    private String board = "         ";
    ReinforcementTraining rt = new ReinforcementTraining();
 
    public String getBoard() {
        return board;
    }
 
    public void setBoard(String board) {
        this.board = board;
    }
 
    public void run() {
        Scanner in = new Scanner(System.in);
 
        board = rt.findBestMove(board);
 
        while (isResume()) {
            int x, y;
 
            System.out.print("line >> ");
            x = in.nextInt();
            System.out.print("column >> ");
            y = in.nextInt();
 
            setO(x, y);
 
            if (isResume()) {
                board = rt.findBestMove(board);
            }
        }
 
        board = "         ";
    }
 
    private boolean isResume() {
        switch (checkWinOrEndGame()) {
            case WIN_X: {
                rt.remember(board, true);
                printBoard();
                printWinX();
                return false;
            }
            case WIN_O: {
                rt.remember(board, false);
                printBoard();
                printWinO();
                return false;
            }
            case END: {
                printEndGame();
                return false;
            }
            case RESUME: {
                printBoard();
                return true;
            }
        }
        return true;
    }
 
    private void inverseBoard() {
        String t1 = board.replaceAll("x", "l");
        board = t1.replaceAll("o", "x");
        board = board.replaceAll("l", "o");
    }
 
    private void printWinX() {
        clearScreen();
        System.out.println("Win X!");
    }
 
    private void printWinO() {
        clearScreen();
        System.out.println("Win O!");
    }
 
    private void printEndGame() {
        clearScreen();
        System.out.println("End Game!");
    }
 
    private State checkWinOrEndGame() {
        double s = rt.evaluation2(board);
        if (s == 10) {
            return State.WIN_X;
        } else if (s == -10) {
            return State.WIN_O;
        }
 
        if (!board.contains(" ")) {
            return State.END;
        }
 
        return State.RESUME;
    }
 
    private void printBoard() {
        clearScreen();
 
        System.out.println("   1 2 3 ");
 
        for (int i = 0; i < 3; i++) {
            System.out.print(i + 1 + " |");
            for (int j = 0; j < 3; j++) {
                System.out.print(board.charAt((i * 3) + j) + "|");
 
            }
            System.out.println();
        }
    }
 
    private void clearScreen() {
        //todo: clear screen
        System.out.flush();
    }
 
    private void setO(int i, int j) {
        i--;
        j--;
 
        char[] temp = board.toCharArray();
        temp[i * 3 + j] = 'o';
 
        StringBuilder b = new StringBuilder();
        b.append(temp);
        board = b.toString();
    }
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.11.2018, 17:11
Ответы с готовыми решениями:

Ищу людей для совместного обучения в области машинного обучения
Пишу на питоне посредством библиотеки keras. Было бы неплохо, например, работать над одним...

Система обучения
Ребят стал такой вопрос, как дальше учить программирование, занимаюсь полтора года, но чего то...

Продолжение обучения C#
Подскажите, пожалуйста. Основы Шилда (полный курс) прочитал. Теперь хотелось бы перейти к Visual...

Начало обучения
почитав различные форумы по обучению питону пришел к выводу что лучше начать обучаться по...

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.11.2018, 17:11

Шаги обучения
Добрый день. Я учусь писать сайты, возможно попробовать на фриласне или пойти в стажеры на back end...

Начало обучения
Добрый день. Появилось желание обучаться программированию. Хотелось бы услышать ваше мнение, с...

Срок обучения C++
Здравствуйте! Учу C++, хочу узнать за сколько его реально можно выучить? Времени полно, могу...

курс обучения
народ,кто учил линукс в универах или спец курсах, поделитесь пжлст планом обучения. набор заданий...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru