From 99a496c0abd15706e5894eb3b737920843cb32bc Mon Sep 17 00:00:00 2001 From: Martin Asprusten Date: Fri, 28 Aug 2026 22:00:17 +0200 Subject: [PATCH] Flatten arrays --- native/salesman.cpp | 110 ++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 66 deletions(-) diff --git a/native/salesman.cpp b/native/salesman.cpp index 824fb15..d62af01 100644 --- a/native/salesman.cpp +++ b/native/salesman.cpp @@ -16,8 +16,8 @@ struct City { }; struct State{ - float** weights; - uint8_t** adjacencyMatrix; + float* weights; + uint8_t* adjacencyMatrix; float lowerBound; bool finished = false; std::vector> paths; @@ -30,14 +30,14 @@ struct SplitState { }; -double reduceWeights(float** weights, int numberOfCities) { +double reduceWeights(float* weights, int numberOfCities) { double totalReduced = 0; for (int row = 0; row < numberOfCities; row++) { double smallestOnRow = 1e100; for (int column = 0; column < numberOfCities; column++) { - if (weights[row][column] < smallestOnRow) { - smallestOnRow = weights[row][column]; + if (weights[row * numberOfCities + column] < smallestOnRow) { + smallestOnRow = weights[row * numberOfCities + column]; } } @@ -48,15 +48,15 @@ double reduceWeights(float** weights, int numberOfCities) { totalReduced += smallestOnRow; for (int column = 0; column < numberOfCities; column++) { - weights[row][column] -= smallestOnRow; + weights[row * numberOfCities + column] -= smallestOnRow; } } for (int column = 0; column < numberOfCities; column++) { double smallestOnColumn = 1e100; for (int row = 0; row < numberOfCities; row++) { - if (weights[row][column] < smallestOnColumn) { - smallestOnColumn = weights[row][column]; + if (weights[row * numberOfCities + column] < smallestOnColumn) { + smallestOnColumn = weights[row * numberOfCities + column]; } } @@ -67,14 +67,14 @@ double reduceWeights(float** weights, int numberOfCities) { totalReduced += smallestOnColumn; for (int row = 0; row < numberOfCities; row++) { - weights[row][column] -= smallestOnColumn; + weights[row * numberOfCities + column] -= smallestOnColumn; } } return totalReduced; } -std::pair findPivotPoint(float** weights, int numberOfCities) { +std::pair findPivotPoint(float* weights, int numberOfCities) { int bestRow = -1; int bestColumn = -1; double bestIncrease = -1; @@ -82,7 +82,7 @@ std::pair findPivotPoint(float** weights, int numberOfCities) { for (int testRow = 0; testRow < numberOfCities; testRow++) { for (int testColumn = 0; testColumn < numberOfCities; testColumn++) { // Only look for pivot cells that have a value of zero - if (weights[testRow][testColumn] > 0.0001) { + if (weights[testRow * numberOfCities + testColumn] > 0.0001) { continue; } @@ -94,8 +94,8 @@ std::pair findPivotPoint(float** weights, int numberOfCities) { continue; } - if (weights[testRow][otherColumn] < smallestOnRow) { - smallestOnRow = weights[testRow][otherColumn]; + if (weights[testRow * numberOfCities + otherColumn] < smallestOnRow) { + smallestOnRow = weights[testRow * numberOfCities + otherColumn]; } } @@ -104,8 +104,8 @@ std::pair findPivotPoint(float** weights, int numberOfCities) { continue; } - if (weights[otherRow][testColumn] < smallestOnColumn) { - smallestOnColumn = weights[otherRow][testColumn]; + if (weights[otherRow * numberOfCities + testColumn] < smallestOnColumn) { + smallestOnColumn = weights[otherRow * numberOfCities + testColumn]; } } @@ -121,10 +121,10 @@ std::pair findPivotPoint(float** weights, int numberOfCities) { return std::pair(bestRow, bestColumn); } -int getDegreeOfNode(int nodeNumber, uint8_t** adjacencyMatrix, int numberOfCities) { +int getDegreeOfNode(int nodeNumber, uint8_t* adjacencyMatrix, int numberOfCities) { int degree = 0; for (int column = 0; column < numberOfCities; column++) { - degree += adjacencyMatrix[nodeNumber][column]; + degree += adjacencyMatrix[nodeNumber * numberOfCities + column]; } return degree; } @@ -160,8 +160,8 @@ void disallowSubloops(State &state, int pivotRow, int pivotColumn, int numberOfC totalDegree += degree; if (degree == 2) { for (int otherNode = 0; otherNode < numberOfCities; otherNode++) { - state.weights[node][otherNode] = 1e100; - state.weights[otherNode][node] = 1e100; + state.weights[node * numberOfCities + otherNode] = 1e100; + state.weights[otherNode * numberOfCities + node] = 1e100; } } } @@ -203,8 +203,8 @@ void disallowSubloops(State &state, int pivotRow, int pivotColumn, int numberOfC int startingNode = state.paths.at(0).first; int endingNode = state.paths.at(0).second; - state.adjacencyMatrix[startingNode][endingNode] = 1; - state.adjacencyMatrix[endingNode][startingNode] = 1; + state.adjacencyMatrix[startingNode * numberOfCities + endingNode] = 1; + state.adjacencyMatrix[endingNode * numberOfCities + startingNode] = 1; state.finished = true; @@ -212,36 +212,34 @@ void disallowSubloops(State &state, int pivotRow, int pivotColumn, int numberOfC } for (std::pair path : state.paths) { - state.weights[path.first][path.second] = 1e100; - state.weights[path.second][path.first] = 1e100; + state.weights[path.first * numberOfCities + path.second] = 1e100; + state.weights[path.second * numberOfCities + path.first] = 1e100; } } State createNewStateOnPivot(int pivotRow, int pivotColumn, State originalState, int numberOfCities) { - uint8_t** adjacencyMatrixCopy = new uint8_t*[numberOfCities]; - float** weightsCopy = new float*[numberOfCities]; + uint8_t* adjacencyMatrixCopy = new uint8_t[numberOfCities * numberOfCities]; + float* weightsCopy = new float[numberOfCities * numberOfCities]; for (int row = 0; row < numberOfCities; row++) { - adjacencyMatrixCopy[row] = new uint8_t[numberOfCities]; - weightsCopy[row] = new float[numberOfCities]; for (int column = 0; column < numberOfCities; column++) { - adjacencyMatrixCopy[row][column] = originalState.adjacencyMatrix[row][column]; - weightsCopy[row][column] = originalState.weights[row][column]; + adjacencyMatrixCopy[row * numberOfCities + column] = originalState.adjacencyMatrix[row * numberOfCities + column]; + weightsCopy[row * numberOfCities + column] = originalState.weights[row * numberOfCities + column]; } } - adjacencyMatrixCopy[pivotRow][pivotColumn] = 1; - adjacencyMatrixCopy[pivotColumn][pivotRow] = 1; + adjacencyMatrixCopy[pivotRow * numberOfCities + pivotColumn] = 1; + adjacencyMatrixCopy[pivotColumn * numberOfCities + pivotRow] = 1; for (int column = 0; column < numberOfCities; column++) { - weightsCopy[pivotRow][column] = 1e100; + weightsCopy[pivotRow * numberOfCities + column] = 1e100; } for (int row = 0; row < numberOfCities; row++) { - weightsCopy[row][pivotColumn] = 1e100; + weightsCopy[row * numberOfCities + pivotColumn] = 1e100; } - weightsCopy[pivotColumn][pivotRow] = 1e100; + weightsCopy[pivotColumn * numberOfCities + pivotRow] = 1e100; State pivotedState; pivotedState.adjacencyMatrix = adjacencyMatrixCopy; @@ -265,11 +263,6 @@ SplitState splitState(State state, int numberOfCities) { std::pair pivotPoint = findPivotPoint(state.weights, numberOfCities); if (pivotPoint.first == -1 || pivotPoint.second == -1) { splitState.wasSplittable = false; - - for (int row = 0; row < numberOfCities; row++) { - delete [] state.adjacencyMatrix[row]; - delete [] state.weights[row]; - } delete [] state.adjacencyMatrix; delete [] state.weights; @@ -279,18 +272,18 @@ SplitState splitState(State state, int numberOfCities) { State pivotedState = createNewStateOnPivot(pivotPoint.first, pivotPoint.second, state, numberOfCities); // Disallow the pivot in the original state - state.weights[pivotPoint.first][pivotPoint.second] = 1e100; + state.weights[pivotPoint.first * numberOfCities + pivotPoint.second] = 1e100; splitState.firstState = pivotedState; splitState.secondState = state; return splitState; } -double getActualWeight(uint8_t** adjacencyMatrix, double** weights, int numberOfCities) { +double getActualWeight(uint8_t* adjacencyMatrix, double* weights, int numberOfCities) { double totalWeight = 0; for (int row = 0; row < numberOfCities; row++) { for (int column = 0; column < numberOfCities; column++) { - totalWeight += adjacencyMatrix[row][column] * weights[row][column]; + totalWeight += adjacencyMatrix[row * numberOfCities + column] * weights[row * numberOfCities + column]; } } @@ -308,13 +301,12 @@ std::vector findShortestPath(std::vector> jsWeights) { int numberOfCities = jsWeights.size(); - double** weights = new double*[numberOfCities]; + double* weights = new double[numberOfCities * numberOfCities]; for (int row = 0; row < numberOfCities; row++) { - weights[row] = new double[numberOfCities]; for (int column = 0; column < numberOfCities; column++) { - weights[row][column] = jsWeights.at(row).at(column); + weights[row * numberOfCities + column] = jsWeights.at(row).at(column); if (column == row) { - weights[row][column] = 1e100; + weights[row * numberOfCities + column] = 1e100; } } } @@ -322,14 +314,12 @@ std::vector findShortestPath(std::vector> jsWeights) { // Create a state State initialState; - initialState.weights = new float*[numberOfCities]; - initialState.adjacencyMatrix = new uint8_t*[numberOfCities]; + initialState.weights = new float[numberOfCities * numberOfCities]; + initialState.adjacencyMatrix = new uint8_t[numberOfCities * numberOfCities]; for (int row = 0; row < numberOfCities; row++) { - initialState.weights[row] = new float[numberOfCities]; - initialState.adjacencyMatrix[row] = new uint8_t[numberOfCities]; for (int column = 0; column < numberOfCities; column++) { - initialState.adjacencyMatrix[row][column] = 0; - initialState.weights[row][column] = weights[row][column]; + initialState.adjacencyMatrix[row * numberOfCities + column] = 0; + initialState.weights[row * numberOfCities + column] = weights[row * numberOfCities + column]; } } initialState.lowerBound = 0; @@ -338,7 +328,7 @@ std::vector findShortestPath(std::vector> jsWeights) { queue.push(initialState); double currentBest = 1e100; - uint8_t** bestAdjacenyMatrix = NULL; + uint8_t* bestAdjacenyMatrix = NULL; while (!queue.empty()) { State nextState = queue.top(); @@ -354,16 +344,8 @@ std::vector findShortestPath(std::vector> jsWeights) { currentBest = actualWeight; bestAdjacenyMatrix = nextState.adjacencyMatrix; } else { - // Delete and clean up memory - for (int row = 0; row < numberOfCities; row++) { - delete [] nextState.adjacencyMatrix[row]; - } delete [] nextState.adjacencyMatrix; } - - for (int row = 0; row < numberOfCities; row++) { - delete [] nextState.weights[row]; - } delete [] nextState.weights; continue; @@ -382,10 +364,6 @@ std::vector findShortestPath(std::vector> jsWeights) { State stateToDelete = queue.top(); queue.pop(); - for (int row = 0; row < numberOfCities; row++) { - delete [] stateToDelete.adjacencyMatrix[row]; - delete [] stateToDelete.weights[row]; - } delete [] stateToDelete.adjacencyMatrix; delete [] stateToDelete.weights; } @@ -402,7 +380,7 @@ std::vector findShortestPath(std::vector> jsWeights) { firstTime = false; for (int column = 0; column < numberOfCities; column++) { - if (bestAdjacenyMatrix[current][column] == 1 && column != previous) { + if (bestAdjacenyMatrix[current * numberOfCities + column] == 1 && column != previous) { previous = current; current = column; break;