double MIDDistanceCalculator::getMIDDistance(std::pair<std::vector<double>, std::vector<double> > const &aligned, size_t origSize1, size_t origSize2) { const std::vector<double> &alV1 = aligned.first; const std::vector<double> &alV2 = aligned.second; // printAlignedVectors(alV1, alV2); double dist; switch(distanceMeasure) { case D_EUCLIDEAN: dist = getEuclideanDistance(alV1, alV2); break; case D_CANBERRA: dist = getCanberraDistance(alV1, alV2); break; case D_MANHATTAN: dist = getManhattanDistance(alV1, alV2); break; case D_COSINE: dist = getCosineCorrelation(alV1, alV2); break; case D_CUSTOM: dist = getCustomDistance(alV1, alV2); break; default: dist = getEuclideanDistance(alV1, alV2); } double divideBy = 1; origSize1 = origSize1?alV1.size():origSize1; origSize2 = origSize2?alV2.size():origSize2; switch(MIDDistanceCalculator::distanceNormalization) { case DN_MAX: divideBy = std::max(origSize1, origSize2); break; case DN_MIN: divideBy = std::min(origSize1, origSize2); break; case DN_PROD: divideBy = origSize1 * origSize2; break; case DN_SUM: divideBy = origSize1 + origSize2; break; } // log(alV2.size()) return fabs(dist / divideBy); }
/* * Requires the beginning cell, the destination cell, and the cell being inspected * Sets "cell"s hval, fval, and gval * returns "cell"s gval */ int getGValue(GridCell* const start, GridCell* const end, GridCell* cell) { int gval = 10, hval = 0, fval = 0; cell->mGValue = 10; if(start->isDiagonalNeighbor(cell)) { gval = 14; cell->mGValue = gval; } hval = getManhattanDistance(cell->getArrayCoords().x, cell->getArrayCoords().y, end->getArrayCoords().x, end->getArrayCoords().y) * 10; cell->mHValue = hval; fval = hval + gval; cell->mFValue = fval; return gval; }
int main(int argc, char *argv[]) { if (argc < 2) { puts("ERR#1: Missing argument!"); return MISSING_PARAMETER; } /* copy argv[1] to variable initState */ char initState[strlen(argv[1])]; strcpy(initState, argv[1]); int i, j; int length = strlen(initState); struct GameState state; /* count rows */ rows = getRowsCount(initState); if (rows == -1) { printf("ERR#2: Malformed input!"); return MALFORMED_INPUT; } /* there is one less semicolon than rows */ rows++; if (rows < MINIMUM_ROWS) { printf("ERR#3: Field too small!"); return FIELD_TOO_SMALL; } /* allocation of memory for initial state of game */ state.tilesPosition = (int **)malloc(rows * sizeof(int *)); if (state.tilesPosition == NULL) { printf("ERR#5: Out of memory!"); return OUT_OF_MEMORY; } for (i = 0; i < rows; i++) { state.tilesPosition[i] = (int *)malloc(rows * sizeof(int *)); if (state.tilesPosition[i] == NULL) { printf("ERR#5: Out of memory!"); return OUT_OF_MEMORY; } for (j = 0; j < rows; j++) { state.tilesPosition[i][j] = 0; } } int usedNumbers[rows * rows]; for (i = 0; i < rows * rows; i++) { usedNumbers[i] = 0; } rows = 0; int cols = 0; int prevCols = 0; int number = 0; for (i = 0; i < length; i++) { if (initState[i] == ';') { /* if count of columns doesn't match, input format isn't right */ if (cols != prevCols && prevCols != 0) { printf("ERR#2: Malformed input!"); return MALFORMED_INPUT; } state.tilesPosition[rows][cols] = number; usedNumbers[number] = 1; /* init for next row */ rows++; prevCols = cols; cols = 0; number = 0; /* if next character after semicolon is space, jump after it */ if (initState[i + 1] == ' ') { i += 2; } } if (initState[i] == ' ') { state.tilesPosition[rows][cols] = number; usedNumbers[number] = 1; cols++; number = 0; } if (isdigit(initState[i])) { number = number * 10 + (initState[i] - 48); } } state.tilesPosition[rows][cols] = number; usedNumbers[number] = 1; rows++; for (i = 0; i < rows * rows; i++) { if (usedNumbers[i] == 0) { printf("ERR#2: Malformed input!"); return MALFORMED_INPUT; } } int isSolvable = isSolvableState(&state); if (isSolvable == 0) { printf("ERR#4: Non-existent solution!"); return NONEXISTENT_SOLUTION; } /* init of first element in priority queue */ state.manhattanDistance = getManhattanDistance(state); state.distance = 0; state.next = (struct GameState *) malloc(sizeof(struct GameState *)); if (state.next == NULL) { printf("ERR#5: Out of memory!"); return OUT_OF_MEMORY; } state.prev = (struct GameState *) malloc(sizeof(struct GameState *)); if (state.prev == NULL) { printf("ERR#5: Out of memory!"); return OUT_OF_MEMORY; } state.next = NULL; state.prev = NULL; /* insert first element to priority queue */ insertPQ(&state); int solved = solveFifteen(); if (solved == OUT_OF_MEMORY) { printf("ERR#5: Out of memory!"); return OUT_OF_MEMORY; } /* system("PAUSE"); */ return 0; }
/** Searches for solution */ int solveFifteen() { struct GameState *queue; int i; while (notEmptyPQ()) { queue = getQueueTop(); if (queue->manhattanDistance == 0) { printSolution(queue); for (i = 0; i < rows; i++) { free(queue->tilesPosition[i]); } free(queue->tilesPosition); free(queue->prev); queue->prev = NULL; /* deallocate memory */ int pocet = 0; while (notEmptyPQ()) { pocet++; free(queue); queue = NULL; queue = getQueueTop(); for (i = 0; i < rows; i++) { free(queue->tilesPosition[i]); } free(queue->tilesPosition); free(queue->prev); queue->prev = NULL; } printf("Ve fronte bylo %d\n", pocet); system("PAUSE"); return 0; } else { int lastMove = getLastMove(queue); if (canMoveLeft(queue) && lastMove != MOVE_RIGHT) { struct GameState *s = createNewState(queue); if (s == NULL) { return OUT_OF_MEMORY; } moveLeft(s); s->manhattanDistance = getManhattanDistance(*s); insertPQ(s); } if (canMoveRight(queue) && lastMove != MOVE_LEFT) { struct GameState *s = createNewState(queue); if (s == NULL) { return OUT_OF_MEMORY; } moveRight(s); s->manhattanDistance = getManhattanDistance(*s); insertPQ(s); } if (canMoveUp(queue) && lastMove != MOVE_DOWN) { struct GameState *s = createNewState(queue); if (s == NULL) { return OUT_OF_MEMORY; } moveUp(s); s->manhattanDistance = getManhattanDistance(*s); insertPQ(s); } if (canMoveDown(queue) && lastMove != MOVE_UP) { struct GameState *s = createNewState(queue); if (s == NULL) { return OUT_OF_MEMORY; } moveDown(s); s->manhattanDistance = getManhattanDistance(*s); insertPQ(s); } } } return 1; }