Existem variações dos tempos de execução regulares da notação Big-O-Notation?

9

Existem várias anotações , como ou e assim por diante. Fiquei me perguntando, se existem variações daquelas na realidade, como ou , ou se são matematicamente incorretas.OO(n)O(n2)O(2n2)O(logn2)

Ou seria correto dizer que é possível melhorar um para um O (3n ^ 2) ? Ainda não posso e não preciso descobrir tempos de execução e não preciso melhorar nada, mas preciso saber se é assim que você descreve suas funções na realidade.O(5n2)O(3n2)

bv_Martn
fonte
11
Não há diferença material entre O (5n ^ 2) e O (3n ^ 2) durante uma análise assintótica. Ambos são O (n ^ 2) e diferem apenas por uma constante. De fato, em uma prova, você pode até reduzir O (5n ^ 2) a O (3n ^ 2) ou O (n ^ 2) para tornar a matemática mais limpa, pois são equivalentes. Ao escrever sua prova, você anota na barra lateral que elas são equivalentes. De fato, você pode até trocar um O (log n) por O (n) e observe que O (log n) <= O (n) na barra lateral. A nota na barra lateral informa ao leitor que é intencional e não um erro de digitação. (Pelo menos foi assim que fiz quando fiz análise de algoritmo na faculdade).
jww 9/05/19
2
Se você estiver usando a notação para se livrar de pequenos fatores, sempre poderá escrever algo como "... melhora o tempo de execução de para ", etc. Ou, equivalentemente, e . Alguns autores preferem escrever como abreviação para o primeiro. Veja, por exemplo, o livro de Trefethen e Bau. O()5n2+o(n2)3n2+o(n2)(5+o(1))n2(3+o(1))n25n2
Yonatan N

Respostas:

21

Fiquei imaginando se existem variações daquelas na realidade, como ou , ou se são matematicamente incorretas.O(2n2)O(log(n2))

Sim, ou são variações válidas.O(2n2)O(log(n2))

No entanto, você os verá raramente, se realmente os vir, principalmente nos resultados finais. A razão é que é . Da mesma forma, é . Isso pode ser surpreendente para iniciantes. No entanto, essas igualdades são mais ou menos a própria razão pela qual grandes anotações foram introduzidas, para ocultar um fator constante multiplicativo que geralmente é difícil de definir e relativamente insignificante.O(2n2) O ( n 2 ) O ( log ( n 2 ) ) O ( log n ) O O(n2)O(log(n2)) O(logn)O

Seria correto dizer que é possível melhorar um para um ?O(5n2)O(3n2)

Não é uma melhoria se a complexidade de tempo de um algoritmo for alterada de para ou de para , porque é enquanto é . Portanto, é incorreto dizer que a complexidade do tempo foi aprimorada de para . É correto dizer que a complexidade temporal de um algoritmo foi aprimorada de para , é claro.O(5n2)O(3n2)Ω(5n2)Ω(3n2)O(5n2)O(3n2)Ω(5n2)Ω(3n2)O(5n2)O(3n2)5n23n2


Exercício 1. Mostre que .O(5n2)=O(3n2)=O(n2)

Exercício 2. Mostre que .O(logn)=O(log(n2))

Exercício 3. Mostre que .Ω(n2+n)=Ω(n2)

John L.
fonte
11
@bv_Martn Aqui está um bom link para entender o que a notação é definido como (apenas simples cálculo limite!): math.stackexchange.com/questions/925053/...O(n)
Akshat Mahajan
2
A única vez que vi fatores constantes na notação O-grande é quando alguém quer dizer que, embora dois algoritmos sejam da mesma classe de complexidade, um deles é estritamente mais rápido que o outro.
Mark
7
@AkshatMahajan A única resposta para essa pergunta /math/925053 está claramente errada. Existem muitas fontes confiáveis ​​em grandes anotações O
John L.
11
"É correto dizer que a complexidade de tempo de um algoritmo foi aprimorada de 5n ^ 2 para 3n ^ 2" - embora o tempo de execução exato frequentemente varie para diferentes tamanhos e valores de entrada. Além disso, isso envolve ponderar todas as operações / focar em uma operação, o que pode não dizer muito sobre os fatores constantes que você obterá no mundo real ou ser comparável a outros algoritmos usando pesos diferentes. Portanto, embora possa haver alguns casos de uso válidos, dizer que algo como o acima é de utilidade limitada (razão pela qual provavelmente é visto raramente).
Dukeling 10/05/19
11
@ Mark: Isso é simplesmente errado.
User21820 11/11/19
13

Você está sempre livre para não usar esta notação. Ou seja, você pode determinar uma função f(n) mais precisa possível e, em seguida, tentar melhorar isso. Por exemplo, você pode ter um algoritmo de classificação que faz comparações f(n) , para tentar criar outro algoritmo de classificação que faça apenas comparações g(n) . Obviamente, todos os tipos de funções f(n) existem (em teoria) e também podem surgir (na prática).

Em vez de tratar a notação Big Oh como mágica misteriosa, na qual é necessário consultar os assistentes para perguntar se você pode fazer alguma coisa, observe a definição . Respeite a definição e faça o que for necessário para realizar seu trabalho.

Juho
fonte
Bem, eu ainda não preciso disso na prática. Ou, na teoria, na verdade, eu só preciso saber se as definições fornecidas pela wikipedia O (1) -O (n!) São as únicas que existem, ou se, na realidade, você pode descrevê-las de maneira diferente se forem diferentes, como O (7N). Meu medo é que, se eu uso que um professor de matemática vai perder suas asas
bv_Martn
11
Existe qualquer definição que alguém faça. Você deve ler com muita atenção o que a notação ou O ( n ! ) Significa, porque sua pergunta não faz sentido. Não há atalhos. Se você quiser entender o que significa um conteúdo matemático, deve estar disposto a investir algum tempo. O(1)O(n!)
Juho
6
@bv_Martn É muito mais provável que o professor de matemática desista, porque você está vendo uma lista de exemplos como uma lista de definições. Muito do objetivo da matemática é definir as coisas de uma maneira que as faça funcionar em geral, não apenas em casos específicos. Sua pergunta é basicamente uma versão mais avançada do "A Wikipedia diz que posso adicionar um e adicionar dois e adicionar dezessete. Mas posso adicionar outros números também?"
precisa saber é o seguinte
7

Embora a resposta aceita seja bastante boa, ela ainda não toca na verdadeira razão pela qual O(n)=O(2n) .

A notação Big-O descreve escalabilidade

Na sua essência, a Notação Big-O não é uma descrição de quanto tempo um algoritmo leva para ser executado. Nem é uma descrição de quantas etapas, linhas de código ou comparações um algoritmo faz. É mais útil quando usado para descrever como um algoritmo é escalonado com o número de entradas.

Faça uma pesquisa binária, por exemplo. Dada uma lista classificada, como você encontra um valor arbitrário dentro dela? Bem, você pode começar do meio. Como a lista é classificada, o valor do meio informará em qual metade da lista está o seu valor-alvo. Portanto, a lista que você precisa pesquisar agora está dividida ao meio. Isso pode ser aplicado recursivamente, passando para o meio da nova lista e assim sucessivamente até o tamanho da lista ser 1 e você encontrar seu valor (ou ele não existe na lista). Dobrar o tamanho da lista adiciona apenas uma etapa extra ao algoritmo, que é um relacionamento logarítmico. Portanto, esse algoritmo é O(logn). O logaritmo é a base 2, mas isso não importa - o núcleo do relacionamento é que multiplicar a lista por um valor constante apenas adiciona um valor constante ao tempo.

Compare uma pesquisa padrão em uma lista não classificada - a única maneira de pesquisar um valor nesse caso é verificar cada uma delas. O pior cenário (que é o que o Big-O implica especificamente) é que seu valor está no final, o que significa que para uma lista de tamanho n , é necessário verificar n valores. Dobrar o tamanho da lista duplica o número de vezes que você deve verificar, que é um relacionamento linear. O(n) . Mas mesmo se você tivesse que executar duas operações em cada valor, algum processamento, por exemplo, o relacionamento linear ainda é válido. O(2n) simplesmente não é útil como descritor, pois descreveria exatamente a mesma escalabilidade que O(n) .

Compreendo que muitas dessas respostas estão basicamente dizendo para você chegar a essa conclusão lendo a definição de Big-O. Mas esse entendimento intuitivo levou um bom tempo para envolver minha cabeça e, por isso, eu a expus o mais claramente possível.

dispersar
fonte
5
O maior problema com esse tipo de resposta é que ele não toca na definição de Big Oh, mas apenas a usa como uma espécie de mágica intuitiva, como em "veja quando você faz isso e isso, é ". Pessoalmente, acho muito mais instrutivo dizer a alguém que o Big Oh não tem absolutamente nada a ver com algoritmos necessariamente e comece com isso. O(n)
Juho
3
@ Juho Instrutivo, talvez, mas finalmente inútil para a grande maioria dos cientistas da computação.
scatter
4
Com isso, devo discordar. Rotular a si mesmo como cientista da computação não deve ser desculpa para não entender o significado de uma notação usada, isto é, pular toda a matemática.
Juho
3
Sim. Não tenho objeção a que os programadores não entendam essas coisas, mas se você quiser se chamar cientista da computação , esse é o principal material.
precisa saber é o seguinte
2
@dkaeae Não, estou me referindo a pessoas que trabalham em outras carreiras no campo, como desenvolvedores de software.
scatter
5

Você pode escrever O(f) para qualquer função f e faz todo o sentido. De acordo com a definição, g(n)=O(f(n)) se houver alguma constante  c tal que g(n)cf(n) para todos grandes o suficiente n . Nada nessa definição diz quef deve ser algum tipo de função "agradável".

Mas, como outras respostas têm apontado, g(n)=O(f(n)) e g(n)=O(2f(n)) descrevem exatamente a mesma situação: se g(n)cf(n) para todos os suficientemente grandes n , então também temosg(n)c22f(n), entãog(n)=O(2f(n)), também (considerando a constantec/2).

Como uma questão secundária, não escreva " logn2 ", porque não está 100% claro do que isso significa. Você poderia dizer que obviamente significa log(n2) mas quase todo mundo escreveria isso como 2logn , o que coloca dúvidas na mente do leitor.

O

David Richerby
fonte
4

Observe a definição de O (f (n)) e veja que, por exemplo, O (2n ^ 2) e O (n ^ 2) são exatamente os mesmos. Alterar um algoritmo de operações de 5n ^ 2 para 3n ^ 2 é uma melhoria de 40%. Mudar de O (5n ^ 2) para O (3n ^ 2) não é realmente nenhuma alteração, eles são os mesmos.

Novamente, leia a definição de O (f (n)).

gnasher729
fonte
4

O(f(n))={g(n)|n,c>0:m>n:c×g(m)f(m)}

=

O(n)=O(2n)

catraca arrepiante
fonte
4
log(n!)=nlognn+O(logn)O(f)