C ++, почему моя рекурсивная функция ведет себя по-разному, когда я сливаю циклы? - PullRequest
0 голосов
/ 29 марта 2020

Я пытаюсь подсчитать количество «шагов» (каждый раз, когда я путешествую к новому узлу, это считается новым шагом), необходимых для прохождения через древовидную структуру с моей рекурсивной функцией.

Способ, которым я намерен работать с функцией, - это пройти весь путь вниз по одному пути к последнему вызову (у меня есть перерыв, чтобы обозначить конец) через рекурсию, go вернуться к предыдущему вызову go на следующий шаг в a для l oop до go в другой узел ...

, затем go обратно в for l oop вызова до этого после for l oop заканчивает ...

вплоть до первого узла, где он движется по другому пути. Я сожалею о плохом объяснении.

Также я не ищу более эффективные алгоритмы обхода, мне просто нужно знать, почему этот алгоритм не работает после того, как я попытался объединить 2 для циклов, и что я можно изменить, чтобы это исправить.

void mario( int current_node, int current_depth ) {
    vector<int> luigi;
    vector<int> wario;
    for( int i = 0; i <= vec[current_node]; i++ ) {

        if( i >= current_node ) {
            if( current_depth != 0 ) {

                luigi.push_back(current_depth - 1);//store new depth
                wario.push_back(i + 1);            //store new_node

            }
            else {
                break;
            }
        }
        else {

            luigi.push_back(current_depth);        //depth stays the same
            wario.push_back(i);                    //store new_node

        }


        }
    for(int r=0; r < luigi.size();r++){

        counter += 1;
        mario(wario[r],luigi[r]);                  //call the function

    }

}

единственное различие между этим и следующим состоит в том, что я сохраняю new_node и new_depth в векторах, а затем вызываю функцию в новом l oop, для меня это казалось дополнительным шагом.

void mario( int current_node, int current_depth ) {
    #pragma omp parallel for schedule(dynamic,1)reduction(+:counter)
    for( int i = 0; i <= vec[current_node]; i++ ) {

        if( i >= current_node ) {
            if( current_depth != 0 ) {
                new_depth = current_depth - 1;
                new_node = i + 1;
            }
            else {
                break;
            }
        }
        else {
            new_depth = current_depth;
            new_node = i; 
        }

        counter+=1;
        mario( new_node, new_depth );
    }  
}
/* why does this behave differently?,or is it the actually equivalent but the problem is elsewhere?*/

с объединенными циклами for и исчезнувшим вектором, новая функция проходит весь путь до последнего вызова, возвращается к предыдущему вызову и завершает для l oop, а затем просто заканчивается, не возвращаясь к вызову до этого и так далее ...

Какие еще непреднамеренные изменения я внес в новую функцию и как я могу их отрицать? Я новичок в C ++ и хочу попробовать и выучить.

Я прошу прощения за мой плохо сформулированный вопрос, если он неясен, пожалуйста, предложите улучшения, которые я могу внести в этот вопрос, чтобы облегчить ответ.

1 Ответ

0 голосов
/ 30 марта 2020

Если я правильно вас понял, вы пытаетесь реализовать обход в глубину .

Одно из различий между двумя примерами кода состоит в том, что второй обращается к глобальным переменным new_depth и new_node в l oop и, насколько я понимаю, строка ниже является директивой OpenMP для распараллеливания l oop.

#pragma omp parallel for schedule(dynamic,1)reduction(+:counter)

Это означает, что вы получаете доступ к общей памяти одновременно без какой-либо синхронизации, что является неопределенным поведением ( data race )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...