Nano Hash - криптовалюты, майнинг, программирование

Объясните временную сложность?

Как найти временную сложность данного алгоритма, обозначенную как N, так и Big-O? Например,

    //One iteration of the parameter - n is the basic variable
void setUpperTriangular (int intMatrix[0,…,n-1][0,…,n-1]) {
         for (int i=1; i<n; i++) { //Time Complexity {1 + (n+1) + n} = {2n + 2}
             for (int j=0; j<i; j++) {  //Time Complexity {1 + (n+1) + n} = {2n + 2}
                 intMatrix[i][j] = 0; //Time complexity {n}
             } 
         } //Combining both, it would be {2n + 2} * {2n + 2} = 4n^2 + 4n + 4 TC
     } //O(n^2)

Является ли временная сложность для этого O (n ^ 2) и 4n ^ 2 + 4n + 4? Если нет, то как вы пришли к своему ответу?

Также у меня есть вопрос о двухпараметрической матрице с временной сложностью.

//Two iterations in the parameter, n^2 is the basic variable
void division (double dividend [0,…,n-1], double divisor [0,…,n-1]) 
 { 
     for (int i=0; i<n; i++) { //TC {1 + (n^2 + 1) + n^2} = {2n^2 + 2}
         if (divisor[i] != 0) { //TC n^2
             for (int j=0; j<n; j++) { //TC {1 + (n^2 + 1) + n^2} = {2n^2 + 2}
                 dividend[j] = dividend[j] / divisor[i]; //TC n^2
             } 
         } 
     } //Combining all, it would be {2n^2 + 2} + n^2(2n^2 + 2) = 2n^3 + 4n^2 + 2 TC
 } //O(n^3)

Будет ли это O(N^3) и 2n^3 + 4n^2 + 2? Опять же, если нет, может кто-нибудь объяснить, почему?

27.01.2014

  • Откуда взялся 4? 27.01.2014
  • Так ты хочешь, чтобы мы сделали твою домашнюю работу? 27.01.2014
  • Я не просил тебя это делать. Я попросил проверить, правильно ли я это сделал. Ясно, что я не просил вас сделать это за меня, так как я уже приложил усилия, чтобы решить задачи. 27.01.2014
  • @ J.Woodring, вероятно, было бы хорошо, если бы вы показали, что вы уже проработали в коде, то есть добавили комментарии к тому, что, по вашему мнению, делает каждый цикл for с точки зрения сложности. 27.01.2014

Ответы:


1

То, что вы ищете в большой временной сложности O, - это приблизительное количество раз, когда инструкция выполняется. Итак, в первой функции у вас есть исполняемый оператор:

intMatrix[i][j] = 0;

Поскольку исполняемый оператор каждый раз занимает одинаковое количество времени, он равен O (1). Итак, для первой функции вы можете сократить ее, чтобы она выглядела так, и вернуться к исполняемому оператору:

i: execute n times{//Time complexity=n*(n+1)/2
    j: execute i times{
        intMatrix[i][j] = 0; //Time complexity=1
    }
}

Возвращаясь назад, цикл i выполняется n раз, а цикл j выполняется i раз. Например, если n = 5, количество выполняемых инструкций будет 5+4+3+2+1=15. Это арифметический ряд, и его можно представить как n(n+1)/2. Таким образом, временная сложность функции составляет n(n+1)/2=n^2/2+n/2=O(n^2).

Для второй функции вы смотрите на что-то подобное. Ваш исполняемый оператор:

dividend[j] = dividend[j] / divisor[i];

Теперь с этим утверждением все немного сложнее, как вы можете видеть из википедии, сложность учебника длинное деление - O (n ^ 2). Однако делимое и делитель НЕ используют вашу переменную n, поэтому они не зависят от нее. Назовем делимое и делитель, он же фактическое содержимое матрицы, «m». Таким образом, временная сложность исполняемого оператора составляет O (m ^ 2). Переходим к упрощению второй функции:

i: execute n times{ //Time complexity=n*(n*(1*m^2))=O(n^2*m^2)
    j: execute n times{ //Time complexity=n*(1*m^2)
        if statement: execute ONCE{ //Time complexity=1*m^2
            dividend[j] = dividend[j] / divisor[i]; //Time complexity=m^2
        }
    }
}

Работая в обратном направлении, вы можете увидеть, что внутренний оператор займет O(m^2), а поскольку оператор if каждый раз занимает одно и то же количество времени, его временная сложность равна O(1). Тогда ваш окончательный ответ будет O(n^2m^2). Поскольку деление занимает так мало времени на современных процессорах, оно обычно оценивается как O(1) (см. of-the-division-operation" rel="nofollow">this для лучшего объяснения того, почему это так), то, что ваш профессор, вероятно, ищет O (n ^ 2) для второй функции.

27.01.2014
  • Отлично, это лучший ответ, который у меня был. Однако сейчас, сидя в классе, она говорит, что нотация Big O для первой функции — это O(n). Ее объяснение таково: поскольку у вас есть матрица в параметрах, переменная по умолчанию равна n^2. Для простоты давайте установим фиктивную переменную s = n^2. Вся функция выполняется s^2 раз. Каким-то образом она от O(s^2) до O(n). Она права...? Все остальные здесь в основном говорят, что ответ, который она только что дала, неверен. 27.01.2014
  • Я только что заметил, что первая функция указывает int j=0; j‹i; j++, а не int j=0; дж‹н; j++. Это означает, что общая функция будет n(n+1)/2=(n^2+n)/2=O(n^2). Все же не O(n). Я изменю свой ответ, чтобы он был правильным. 27.01.2014
  • Это зависит от того, считает ли она n размером матрицы или размером стороны матрицы. Согласно функции, которую она вам дала, n — это не размер матрицы, это длина стороны, поэтому временная сложность по-прежнему должна быть O(n^2). Если она хотела чего-то другого, она должна была указать в задаче. 27.01.2014

  • 2

    Оба O(N2). Вы обрабатываете N2 элементов в худшем случае.

    Второй пример может быть просто O(N) в лучшем случае (если второй аргумент состоит из нулей).

    Я не уверен, как вы получаете другие полиномы. Обычно точная сложность значения не имеет (именно при работе с языком более высокого уровня).

    27.01.2014
  • Почему второй O (n ^ 2)? 27.01.2014

  • 3

    Обозначение Big O или временная сложность описывает взаимосвязь между изменением размера данных (n) и величиной времени/пространства, необходимого данному алгоритму для его обработки.

    В вашем случае у вас есть две петли. Для каждого числа n (внешний цикл) вы обрабатываете n элементов (во внутреннем цикле) элементов. Таким образом, у вас есть O(n2) или "квадратичная" временная сложность.

    Таким образом, для небольших чисел n разница незначительна, но для больших чисел n она быстро сходит на нет.

    Исключение 0 из делителя, как в алгоритме 2, существенно не меняет временную сложность, потому что проверка того, является ли число = 0 равным O(1) и на несколько порядков меньше, чем O(n2) . Устранение внутреннего цикла в этом конкретном случае по-прежнему занимает O(n), и время, необходимое для выполнения O(n2), по-прежнему незначительно. Таким образом, ваш второй алгоритм технически становится (в лучшем случае) O (n) (если в ряду делителей есть только нули).

    27.01.2014
  • Таким образом, несмотря на то, что if во второй задаче обрабатывается каждый раз в цикле for, технически она по-прежнему обрабатывается только один раз? 27.01.2014
  • Нет. Есть только два сценария, в которых оператор if является статистически значимым. Случай, когда все входы равны 0, поэтому внутренний цикл никогда не выполняется (лучший случай) или случай, когда все входы отличны от нуля, поэтому внутренний цикл выполняется все время. Сама проверка if - это O(1), так что да, конечно, если вы хотите быть педантичным, это O(n*n*1) в худшем случае или O(n*1) в лучшем случае. :) 27.01.2014
  • Ооо, кажется, теперь я понимаю. Благодарю вас! 27.01.2014
  • Быть педантичным => O(n*n + n*1) (n-кратное выполнение цикла с n итерациями плюс n-кратное выполнение проверки всегда верно) для наихудшего случая. Но тогда вы можете задаться вопросом, следует ли вам учитывать проверку условия цикла for и приращение и т. д. (вот почему большой O полезен - он устраняет такие вопросы). 27.01.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..