int maxArrayWithAlThree(int *array, int start, int end){ if(start == (end - 1)){ return Max(array[start], array[end], array[start] + array[end]); } if(start == end) return array[start]; int mid = (start + end) / 2; int left = maxArrayWithAlThree(array, start, mid); int right = maxArrayWithAlThree(array, mid + 1, end); return Max(left, right, crossSum(array, start, mid, end)); }
std::tuple<double, ValueFunction> IncrementalPruning::operator()(const M & model) { // Initialize "global" variables S = model.getS(); A = model.getA(); O = model.getO(); auto v = makeValueFunction(S); // TODO: May take user input unsigned timestep = 0; Pruner prune(S); Projecter projecter(model); const bool useTolerance = checkDifferentSmall(tolerance_, 0.0); double variation = tolerance_ * 2; // Make it bigger while ( timestep < horizon_ && ( !useTolerance || variation > tolerance_ ) ) { ++timestep; // Compute all possible outcomes, from our previous results. // This means that for each action-observation pair, we are going // to obtain the same number of possible outcomes as the number // of entries in our initial vector w. auto projs = projecter(v[timestep-1]); size_t finalWSize = 0; // In this method we split the work by action, which will then // be joined again at the end of the loop. for ( size_t a = 0; a < A; ++a ) { // We prune each outcome separately to be sure // we do not replicate work later. for ( size_t o = 0; o < O; ++o ) { const auto begin = std::begin(projs[a][o]); const auto end = std::end (projs[a][o]); projs[a][o].erase(prune(begin, end, unwrap), end); } // Here we reduce at the minimum the cross-summing, by alternating // merges. We pick matches like a reverse binary tree, so that // we always pick lists that have been merged the least. // // Example for O==7: // // 0 <- 1 2 <- 3 4 <- 5 6 // 0 ------> 2 4 ------> 6 // 2 <---------------- 6 // // In particular, the variables are: // // - oddOld: Whether our starting step has an odd number of elements. // If so, we skip the last one. // - front: The id of the element at the "front" of our current pass. // note that since passes can be backwards this can be high. // - back: Opposite of front, which excludes the last element if we // have odd elements. // - stepsize: The space between each "first" of each new merge. // - diff: The space between each "first" and its match to merge. // - elements: The number of elements we have left to merge. bool oddOld = O % 2; int i, front = 0, back = O - oddOld, stepsize = 2, diff = 1, elements = O; while ( elements > 1 ) { for ( i = front; i != back; i += stepsize ) { projs[a][i] = crossSum(projs[a][i], projs[a][i + diff], a, stepsize > 0); const auto begin = std::begin(projs[a][i]); const auto end = std::end (projs[a][i]); projs[a][i].erase(prune(begin, end, unwrap), end); --elements; } const bool oddNew = elements % 2; const int tmp = back; back = front - ( oddNew ? 0 : stepsize ); front = tmp - ( oddOld ? 0 : stepsize ); stepsize *= -2; diff *= -2; oddOld = oddNew; } // Put the result where we can find it if (front != 0) projs[a][0] = std::move(projs[a][front]); finalWSize += projs[a][0].size(); } VList w; w.reserve(finalWSize); // Here we don't have to do fancy merging since no cross-summing is involved for ( size_t a = 0; a < A; ++a ) w.insert(std::end(w), std::make_move_iterator(std::begin(projs[a][0])), std::make_move_iterator(std::end(projs[a][0]))); // We have them all, and we prune one final time to be sure we have // computed the parsimonious set of value functions. const auto begin = std::begin(w); const auto end = std::end (w); w.erase(prune(begin, end, unwrap), end); v.emplace_back(std::move(w)); // Check convergence if ( useTolerance ) variation = weakBoundDistance(v[timestep-1], v[timestep]); } return std::make_tuple(useTolerance ? variation : 0.0, v); }
int main(){ //*****************************test arrays************************************** int array1[] = {-11, 44, 40, -26, -5, 48, 19, -6, 25, 48, -28, 1, 23, -16, 24, 37, 12, -19, -3, -19, -13, 22, -11, 47, -16, -5, 0, 16, 29, -46, 1}; int array2[] = {-20, 4, -19, 43, -18, 17, 50, 7, 40, -4, 13, 34, 42, -15, -17, -38, -49, 20, -46, -35, -41, -16, 42, 22, 0, -38, 9, 28, 25, 15, -37, 34, 17, -12, 43, 12, -37, -44, -45, 45, -39, 10, -46, -9, 27, 11, -27, -32, -3, 50}; int array3[] = {-42, 26, 10, -38, 27, 4, 28, -16, 32, -38, -49, -26, 18, -44, 24, -24, -16, 11, 41, 38, -40, 23, -13, -37, -42, 21, 23, 47, -17, 3, -23, 15, 5, 47, -13, -35, 3, 26, -4, 8, 8}; int array4[] = {-8, 6, 38, 35, 23, 30, 16, -2, -50, -41, -13, -38, 17, -12, -16, -12, 20, -47, -40, -39, 37, -46, 36, 26, 16, 13}; int array5[] = {34, 36, -37, 23, 23, 8, -2, -15, -36, 5, 44, 21, -42, 17, -14, -30, 37, 21, -16, 18, 49, 36, -36, -8, 38, -40, -14, 40, -4, 0, -35, -34}; int array6[] = {-50, 31, 25, -12, 13, -20, 46, -12, -32, 44, -25, -50, 16, -5, -30, 25, -25, -34, -6, -28, 4, 6, -41, 6, 44, -50, 5, 18, 44, -39, 9, 28, 2, -12, -2, -21, -39, -17, 1, 27, 22, 41, -20, -27, 36, 46, 43}; int array7[] = {-46, -35, -15, -50, 45, -6, 19, 25, 25, -5, -50, -31, 49, -25, -30, -21, -11, -48, 9, -27, 32, 3, -9, -41, 20, -45, 22, 47, -33, 6, 40, -30}; int array8[] = {21, -44, -19, -17, 23, -43, -26, 17, -44, 39, -6, 12, -28, -16, -36, -23, -27, 42, -26, -12, 8, 48, -41, -41, -11, 46, 44, -30, -44, -49, 15, 43, 47, -22}; int array9[] = {26, -17, 8, -18, 32, 16, -50, -43, 22, -25, -23, 32, 27, -14, -44, -3, 8, -19, 28, -45, -6, 29, 30, -24, -37}; int array10[] = {-5, -22, -26, -42, -40, -33, 10, 15, -27, 26, 21, 2, 49, 13, 44, 43, 35, 30, 9, 12, 49, -39, 33, 34, 2, 34, -40, -13, 0, 14}; int array11[] = {36, 40, -8, 28, 38, -38, 24, -33, -27, -18, 26, 9, 9, 38, -35, 11, 36, -17, 20, 45, -9, 27, -24, -27, -28, -25, 41, -46, 29, 27, 34, -28, -44, -6, 26, 42, -16, 40, 27, 14, 22, 37, -26, 46, 21, 45, -40, -25, 5, 50}; int array12[] = {5, 12, 34, 10, 20, 50, -38, 39, -27, 37, 23, 34, 19, 0, 18, -9, -14, 2, -8, -16, 34, 2}; int array13[] = {-11, -14, -21, -2, -28, 37, -9, -35, -33, -18, -42, -44, 25, -32, 33, -44, -16, -42, 44, -43, -25, -39, -3, 31, -46, -41, 38, -49, 11, 11, 28, -22, -44}; int array14[] = {-38, -22, 46, -43, 16, -47, 21, -31, 34, 43, -9, -40, -41, 17, 32, -7, -46, -39, 44, 10, -8, 23, -23, 31, 3, 2, -10, -11, 10}; int array15[] = {2, -11, -7, 31, -18, 11, 10, 12, 33, -36, -44, 33, 4, 28, 39, 20, 1, 45, 38, -48, -26, 26, 35, 50, 26, -7, -45, -25, -29, 28, -47, -50, 15, 38, -3, -6, -39, 20, 45, 4, -32, 23, 48, 39, 3}; int array16[] = {-4, 46, -30, 37, 33, 38, 1, -24, -39, 22, 0, 14, -1, 31, 28, -1, 15, 15, 40, 0, 12, 49, 38, -33, 16, -9, -49, 44, 41, -33, -8, -32, -29, -47, 16, 44, -45, 47, -25}; int array17[] = {47, -5, -6, -22, -2, -37, 37, 21, -45, 3, 7, -42, 24, -12, -12, 15, -3, -12, 1, 29, -47, -1, -30, -31, 23, 28, 23, 38, 39, 42, -5, -4, -31, -31}; int array18[] = {26, -14, 38, 44, -9, -18, 17, 41, 24, -1, 42, -36, 37, -17, -28, -26, -44, -23, 1, -16, -9, 9, 14, -48, -11, 49, 36, -3, 43, -15, 4, -17, 17, -1, 44, 28, -14, 50, -21, -3, 13, -6, -44, -22, -37, 40, -10}; int array19[] = {-44, -47, -48, 17, 47, 3, -3, -20, -3, -20, 9, -4, -25, -22, 13, 11, -3, 12, -13, -20, 3}; //************************************************************************** int *arrays[19] = {array1, array2, array3, array4, array5, array6, array7, array8, array9, array10, array11, array12, array13, array14, array15, array16, array17, array18, array19}; double timeElapsed; clock_t start, end; int i; //counter int _arraySize[19]; _arraySize[0] = elementInArray(sizeof(array1), (int)sizeof(int)); _arraySize[1] = elementInArray(sizeof(array2), (int)sizeof(int)); _arraySize[2] = elementInArray(sizeof(array3), (int)sizeof(int)); _arraySize[3] = elementInArray(sizeof(array4), (int)sizeof(int)); _arraySize[4] = elementInArray(sizeof(array5), (int)sizeof(int)); _arraySize[5] = elementInArray(sizeof(array6), (int)sizeof(int)); _arraySize[6] = elementInArray(sizeof(array7), (int)sizeof(int)); _arraySize[7] = elementInArray(sizeof(array8), (int)sizeof(int)); _arraySize[8] = elementInArray(sizeof(array9), (int)sizeof(int)); _arraySize[9] = elementInArray(sizeof(array10), (int)sizeof(int)); _arraySize[10] = elementInArray(sizeof(array11), (int)sizeof(int)); _arraySize[11] = elementInArray(sizeof(array12), (int)sizeof(int)); _arraySize[12] = elementInArray(sizeof(array13), (int)sizeof(int)); _arraySize[13] = elementInArray(sizeof(array14), (int)sizeof(int)); _arraySize[14] = elementInArray(sizeof(array15), (int)sizeof(int)); _arraySize[15] = elementInArray(sizeof(array16), (int)sizeof(int)); _arraySize[16] = elementInArray(sizeof(array17), (int)sizeof(int)); _arraySize[17] = elementInArray(sizeof(array18), (int)sizeof(int)); _arraySize[18] = elementInArray(sizeof(array19), (int)sizeof(int)); FILE *fp = fopen("results.txt", "w"); if(fp != NULL) fprintf(fp, "Algorithm 1: "); else{ printf("Fail to create file\n"); return 1; } //algorithm 1 for(i = 0; i < 19; i++){ start = clock(); int largest1 = maxArrayWithAlOne(arrays[i], _arraySize[i]); end = clock(); timeElapsed = (end - start) * 1000 /CLOCKS_PER_SEC; fprintf(fp, "%d ", largest1); } fprintf(fp, "\n"); //algorithm 2 fprintf(fp, "Algorithm 2: "); for(i = 0; i < 19; i++){ start = clock(); int largest2 = maxArrayWithAlTwo(arrays[i], _arraySize[i]); end = clock(); timeElapsed = (end - start) * 1000 / CLOCKS_PER_SEC; fprintf(fp, "%d ", largest2); } fprintf(fp, "\n"); //algorithm 3 fprintf(fp, "Algorithm 3: "); for(i = 0; i < 19; i++){ start = clock(); int mid = _arraySize[i] / 2; int largest3 = Max(maxArrayWithAlThree(arrays[i], 0, mid), maxArrayWithAlThree(arrays[i], mid + 1, _arraySize[i] - 1), crossSum(arrays[i], 0, mid, _arraySize[i] - 1)); end = clock(); timeElapsed = (end - start) * 1000 / CLOCKS_PER_SEC; fprintf(fp, "%d ", largest3); } fprintf(fp, "\n"); close(fp); return 0; }