diff --git a/MainTomasz.cpp b/MainTomasz.cpp index 4dc233d..e4a96dc 100644 --- a/MainTomasz.cpp +++ b/MainTomasz.cpp @@ -27,6 +27,12 @@ int pozycjaTraktoraX = 1, pozycjaTraktoraY = 1; char currentWay = 'S'; char underTraktor = '.'; double timeToDest = 0.0; +double **weightMatrix; +double neuroOutputPole[25][25]; +double *inputNeurons; +double **grad; +double **avrGrad; +double numberOfTests; void color(string foregroundColor, string backgroundColor) { @@ -546,7 +552,21 @@ double countTimeToDest(int endX, int endY) double Sigmoid(double number) { - return (number / (1.0 + abs(number))); + int tempInt = 0; + if (number < 0) + { + tempInt = 1; + } + return tempInt + (number / (1.0 + abs(number))); +} +double pSigmoid(double number) +{ + int tempInt = 1; + if (number < 0) + { + tempInt = -1; + } + return tempInt * (number / ((1.0 + abs(number))*(1.0 + abs(number)))); } double lookOfVege(int x, int y) { @@ -585,18 +605,90 @@ double lookOfVege(int x, int y) return 5.0; } } -double setValusesRange(double a, double b, double x) +double setValusesRange(double a, double b, double num) { - double avr = ((a + b) / 2); - return Sigmoid(x - avr); + int temp = 1; + if (a > b) + { + temp = -1; + } + double avr = ((a + b) / 2)*temp; + return Sigmoid(num - avr); +} +void gradient(int desiredOutput[25][25]) +{ + const int numberOfCellsInPole = (25 * 25); + const int inputNeuronsCount = numberOfCellsInPole * 4; + grad = (double **)malloc(numberOfCellsInPole * sizeof(double *)); + for (int i = 0; i < numberOfCellsInPole; i++) + { + grad[i] = (double *)malloc(inputNeuronsCount * sizeof(double)); + } + double z; + for (int i = 0; i < numberOfCellsInPole; i++) + { + for (int j = 0; j < inputNeuronsCount; j++) + { + if (weightMatrix[i][j] != 0) + { + int x, y; + y = i / 25; + x = i % 25; + grad[i][j] = 2 * pSigmoid(weightMatrix[i][j] * inputNeurons[j]) * inputNeurons[j] * (neuroOutputPole[y][x] - desiredOutput[y][x]); + } + else + { + grad[i][j] = 0; + } + } + } + //cout << "grad set" << endl; } -void firstHiddenLayer() + +void buildMatrix() { - //25*25-1 + const int numberOfCellsInPole = (25 * 25); + const int inputNeuronsCount = numberOfCellsInPole * 4; + weightMatrix = (double **)malloc(numberOfCellsInPole * sizeof(double *)); + for (int i = 0; i < numberOfCellsInPole; i++) + { + weightMatrix[i] = (double *)malloc(inputNeuronsCount * sizeof(double)); + } + for (int i = 0; i < numberOfCellsInPole; i++) + { + for (int j = 0; j < inputNeuronsCount; j++) + { + if (j >= (i * 4) && j < ((i + 1) * 4)) + { + weightMatrix[i][j] = 1.0; + } + else + { + weightMatrix[i][j] = 0.0; + } + } + } +} +void buildAvrGrad() +{ + const int numberOfCellsInPole = (25 * 25); + const int inputNeuronsCount = numberOfCellsInPole * 4; + avrGrad = (double **)malloc(numberOfCellsInPole * sizeof(double *)); + for (int i = 0; i < numberOfCellsInPole; i++) + { + avrGrad[i] = (double *)malloc(inputNeuronsCount * sizeof(double)); + } + for (int i = 0; i < numberOfCellsInPole; i++) + { + for (int j = 0; j < inputNeuronsCount; j++) + { + avrGrad[i][j] = 0; + } + } } -void neuronsInputBuild() +double neuronsInputBuild(int desiredOutput[25][25]) { const int numberOfCellsInPole = (25 * 25);// -1; const int inputNeuronsCount = numberOfCellsInPole * 4; @@ -610,32 +702,193 @@ void neuronsInputBuild() { for (int j = 1; j <= 25; j++) { - if (pole[i][j][0] != 'T') + int tempCell = (((i - 1) * 25) + (j - 1)); + if (pole[i][j][0] == 'T') { - int tempCell = (((i - 1) * 25) + (j - 1)); - if (j >= pozycjaTraktoraX && i >= pozycjaTraktoraY) + /*if (j >= pozycjaTraktoraX && i >= pozycjaTraktoraY) { int tempCell = (((i - 1) * 25) + (j - 1))-1; - } - typeOfVege[tempCell] = setValusesRange(1, 9, pole[i][j][1]);//type after weight 1-9 - timeToGetToVege[tempCell] = setValusesRange(0, 25 * 25 * 9, countTimeToDest(j, i));//time x.0 - protectOrFertilize[tempCell] = setValusesRange(0, 3, poleInt[i][j][0]);//0.0 1.0 2.0 3.0 - stateOfVege[tempCell] = setValusesRange(0, 5, lookOfVege(j, i));//0.0-5.0*/ + }*/ + typeOfVege[tempCell] = 0;//type after weight 1-9 + timeToGetToVege[tempCell] = 0;//time x.0 + protectOrFertilize[tempCell] = 0;//0.0 1.0 2.0 3.0 + stateOfVege[tempCell] = 0;//0.0-5.0 + } + else + { + typeOfVege[tempCell] = setValusesRange(1, 9, ((double)pole[i][j][1]-48));//type after weight 1-9 + timeToGetToVege[tempCell] = setValusesRange(25 * 9, 0, countTimeToDest(j, i));//time x.0 + protectOrFertilize[tempCell] = setValusesRange(3, 0, poleInt[i][j][0]);//0.0 1.0 2.0 3.0 + stateOfVege[tempCell] = setValusesRange(0, 5, lookOfVege(j, i));//0.0-5.0 } } } - cout << "set neutrons"; - double **weightMatrix = (double **)malloc(inputNeuronsCount * sizeof(double *)); - for (int i = 0; i < inputNeuronsCount; i++) + //cout << "set neurons"; + inputNeurons = (double *)malloc(inputNeuronsCount * sizeof(double)); + for (int i = 0; i < numberOfCellsInPole; i++) { - weightMatrix[i] = (double *)malloc(numberOfCellsInPole * sizeof(double)); + inputNeurons[i * 4] = typeOfVege[i]; + inputNeurons[(i * 4) + 1] = timeToGetToVege[i]; + inputNeurons[(i * 4) + 2] = protectOrFertilize[i]; + inputNeurons[(i * 4) + 3] = stateOfVege[i]; } - - firstHiddenLayer(); - -} + /*double **weightMatrix = (double **)malloc(numberOfCellsInPole * sizeof(double *)); + for (int i = 0; i < numberOfCellsInPole; i++) + { + weightMatrix[i] = (double *)malloc(inputNeuronsCount * sizeof(double)); + } + for (int i = 0; i < numberOfCellsInPole; i++) + { + for (int j = 0; j < inputNeuronsCount; j++) + { + if (j >= (i * 4) && j < ((i + 1) * 4)) + { + weightMatrix[i][j] = 1; + } + else + { + weightMatrix[i][j] = 0; + } + } + }*/ + //0 1 2 inp + //1 + //2 + //num + //inp -> a inp(0-3) + //inp -> a1 inp(4-7) + //inp -> a2 inp(8-11) + + //updatePola(); + //cout << "matrix setup"; + + //firstHiddenLayer(); + //updatePola(); + double *outputLayer = (double *)malloc(numberOfCellsInPole * sizeof(double)); + for (int i = 0; i < numberOfCellsInPole; i++) + { + double sum = 0; + for (int j = 0; j < inputNeuronsCount; j++) + { + sum += weightMatrix[i][j] * inputNeurons[j]; + } + outputLayer[i] = Sigmoid(sum); + } + for (int i = 0; i < 25; i++) + { + for (int j = 0; j < 25; j++) + { + int tempCell = ((i * 25) + j); + neuroOutputPole[i][j] = outputLayer[tempCell]; + } + } + double cost = 0.0; + for (int i = 0; i < 25; i++) + { + for (int j = 0; j < 25; j++) + { + double tempNum = neuroOutputPole[i][j] - desiredOutput[i][j]; + cost += (tempNum*tempNum); + } + } + //updatePola(); + return cost; +} +void backProp(int desiredOuput[25][25]) +{ + /*double node[25][25]; + for (int i = 0; i < 25; i++) + { + for (int j = 0; j < 25; j++) + { + double tempNum = neuroOutputPole[i][j] - desiredOuput[i][j]; + node[i][j] = (tempNum*tempNum); + } + } + cout << neuroOutputPole[1][2] << endl;//->0 + cout << neuroOutputPole[4][3] << endl;//->1 + updatePola();*/ + + const int numberOfCellsInPole = (25 * 25); + const int inputNeuronsCount = numberOfCellsInPole * 4; + double cost; + cost = neuronsInputBuild(desiredOuput); + int i = 0; + while (cost > 50 && i<30) + { + cout << i << " "; + gradient(desiredOuput); + + for (int i = 0; i < numberOfCellsInPole; i++) + { + for (int j = 0; j < inputNeuronsCount; j++) + { + //cout << grad[i][j] << " "; + weightMatrix[i][j] -= grad[i][j]; + } + } + + cost = neuronsInputBuild(desiredOuput); + i++; + } + cout << "--END--" << endl; + for (int i = 0; i < numberOfCellsInPole; i++) + { + for (int j = 0; j < inputNeuronsCount; j++) + { + if (weightMatrix[i][j] != 0) + { + avrGrad[i][j] += 1 - weightMatrix[i][j]/numberOfTests; + } + } + } + //double cost = neuronsInputBuild(desiredOuput); + //cout << oldcost << endl; + //cout << cost << endl; + /* + for (int i = 0; i < 25; i++) + { + for (int j = 0; j < 25; j++) + { + if (desiredOuput[i][j] == 1) + { + cout << "!!" << node[i][j] << "!! "; + } + else + { + cout << node[i][j] << " "; + } + } + }*/ +} +void network(int desiredX,int desiredY) +{ + int desiredPole[25][25]; + for (int i = 0; i < 25; i++) + { + for (int j = 0; j < 25; j++) + { + desiredPole[i][j] = 0; + } + } + desiredPole[desiredY - 1][desiredX - 1] = 1; + //double cost = neuronsInputBuild(desiredPole); + backProp(desiredPole); +} +void bestMatrixBuild() +{ + const int numberOfCellsInPole = (25 * 25); + const int inputNeuronsCount = numberOfCellsInPole * 4; + for (int i = 0; i < numberOfCellsInPole; i++) + { + for (int j = 0; j < inputNeuronsCount; j++) + { + weightMatrix[i][j] -= avrGrad[i][j]; + } + } +} void test1() { @@ -704,6 +957,46 @@ void start3() gogo(goalX, goalY); } +void neuroTest1(int bX,int bY) +{ + pole[bY][bX][0] = 'B'; + pole[bY][bX][1] = '9'; + poleInt[bY][bX][0] = 0; + poleInt[bY][bX][1] = 16; + updatePola(); + network(bX, bY); + pole[bY][bX][0] = '.'; + pole[bY][bX][1] = '1'; + poleInt[bY][bX][0] = 0; + poleInt[bY][bX][1] = 0; + updatePola(); +} +void neuroTest2() +{ + int bX[5] = { 4,24,24,25,25 }, bY[5] = {5,1,2,2,1}; + for (int i = 0; i < 5; i++) + { + pole[bY[i]][bX[i]][0] = 'B'; + pole[bY[i]][bX[i]][1] = '9'; + poleInt[bY[i]][bX[i]][0] = 0; + poleInt[bY[i]][bX[i]][1] = 8; + } + poleInt[bY[4]][bX[4]][0] = 3; + poleInt[bY[4]][bX[4]][1] = 70; + updatePola(); + + network(bX[4], bY[4]); + + for (int i = 0; i < 5; i++) + { + pole[bY[i]][bX[i]][0] = '.'; + pole[bY[i]][bX[i]][1] = '1'; + poleInt[bY[i]][bX[i]][0] = 0; + poleInt[bY[i]][bX[i]][1] = 0; + } + updatePola(); +} + void neuroStart1() { int b1X = 4, b1Y = 5; @@ -715,10 +1008,87 @@ void neuroStart1() pozycjaTraktoraX = 1, pozycjaTraktoraY = 1; pole[pozycjaTraktoraY][pozycjaTraktoraX][0] = 'T'; pole[pozycjaTraktoraY][pozycjaTraktoraX][1] = '1'; + //underTraktor='B' + //pole[pozycjaTraktoraY][pozycjaTraktoraX][1] = '9'; + buildMatrix(); + buildAvrGrad(); + numberOfTests = 6; + neuroTest1(b1X, b1Y); + buildMatrix(); + neuroTest1(b2X, b2Y); + buildMatrix(); + neuroTest1(b3X, b3Y); + buildMatrix(); + neuroTest1(b4X, b4Y); + buildMatrix(); + neuroTest1(b5X, b5Y); + buildMatrix(); + neuroTest2(); + buildMatrix(); + + bestMatrixBuild(); +} + +void chousePath() +{ + int tempOut[25][25]; + for (int i = 0; i < 25; i++) + { + for (int j = 0; j < 25; j++) + { + tempOut[i][j] = 0; + } + } + neuronsInputBuild(tempOut); + const int numberOfCellsInPole = (25 * 25); + const int inputNeuronsCount = numberOfCellsInPole * 4; + double bestX=0, bestY=0, bestChance=1; + for (int i = 0; i < 25; i++) + { + for (int j = 0; j < 25; j++) + { + //cout << neuroOutputPole[i][j] << " "; + + double tempChance; + if (pole[i + 1][j + 1][0] == 'T') + { + tempChance = 1; + } + else + { + tempChance = neuroOutputPole[i][j]; + } + //cout << tempChance << " "; + if (tempChance < bestChance) + { + bestX = j; + bestY = i; + bestChance = tempChance; + } + } + } + //cout << bestChance << " " << bestX + 1 << " " << bestY + 1 << endl; + //Sleep(10000); + gogo(bestX+1, bestY+1); + //Sleep(100000); +} + +void testOfNeuroMove() +{ + pole[1][2][0] = 'B'; + pole[1][2][1] = '9'; + poleInt[1][2][0] = 0; + poleInt[1][2][1] = 50; + pole[1][3][0] = 'B'; + pole[1][3][1] = '9'; + poleInt[1][3][0] = 0; + poleInt[1][3][1] = 60; + pole[1][4][0] = 'B'; + pole[1][4][1] = '9'; + poleInt[1][4][0] = 0; + poleInt[1][4][1] = 70; updatePola(); - - neuronsInputBuild(); } int main() @@ -754,6 +1124,9 @@ int main() //start3(); // testy start 1-3 neuroStart1(); + + testOfNeuroMove(); + //---------start---------// bool traktorDziala = true; @@ -761,15 +1134,16 @@ int main() do { - akcja = _getch(); - if (akcja == 'w' || akcja == 's' || akcja == 'a' || akcja == 'd') + chousePath(); + /*akcja = _getch(); + /if (akcja == 'w' || akcja == 's' || akcja == 'a' || akcja == 'd') { Move(akcja); } if (akcja == '0') { traktorDziala = false; - } + }*/ } while (traktorDziala); //---------end---------//