Como observa Ariel , o algoritmo padrão de localização máxima fornecido abaixo:
def find_maximum(a):
m = a[0]
for x in a:
if x > m: m = x
return m
de fato funcionará sem modificações, desde que:
- qualquer par de elementos pode ser comparado e
- é garantido que a entrada contém um elemento máximo, ou seja, um elemento que é emparelhado maior do que qualquer outro elemento na entrada.
(O primeiro pressuposto acima realmente pode ser relaxada, mesmo sem ter que modificar o algoritmo, desde que assumimos que o elemento máxima é comparável com todos os outros elementos e que x > y
é sempre false se os elementos x
e y
são incomparáveis.)
Em particular, você afirma que:
[…] Para ter certeza de uma resposta, o elemento precisa ser explicitamente comparado a qualquer outro elemento (porque a comparação não é transitiva).
não é verdade sob as premissas fornecidas acima. De fato, para provar que o algoritmo acima sempre encontrará o elemento máximo, basta observar que:
- desde que o loop itere sobre todos os elementos de entrada, em alguma iteração
x
será o elemento máximo;
- como o elemento máximo é maior em pares do que qualquer outro elemento, segue-se que, no final dessa iteração,
m
será o elemento máximo; e
- como nenhum outro elemento pode ser emparelhado maior que o elemento máximo, segue-se que
m
não será alterado em nenhuma das iterações subsequentes.
Portanto, no final do loop, m
sempre será o elemento máximo, se a entrada contiver um.
Ps. Se a entrada nem sempre necessariamente contém um elemento máximo, a verificação desse fato exigirá um teste da resposta do candidato em relação a qualquer outro elemento para verificar se ele é realmente máximo. No entanto, ainda podemos fazer isso em O ( n ) tempo após a execução do algoritmo de localização máxima acima:
def find_maximum_if_any(a):
# step 1: find the maximum, if one exists
m = a[0]
for x in a:
if x > m: m = x
# step 2: verify that the element we found is indeed maximal
for x in a:
if x > m: return None # the input contains no maximal element
return m # yes, m is a maximal element
(Estou assumindo aqui que a relação >
é irreflexiva, ou seja, nenhum elemento pode ser maior que ele próprio. Se esse não for necessariamente o caso, a comparação x > m
na etapa 2 deve ser substituída por x ≠ m and x > m
, onde ≠
denota comparação de identidade. Ou podemos aplicar a otimização indicado abaixo.)
Para provar a correção dessa variação do algoritmo, considere os dois casos possíveis:
- Se a entrada contiver um elemento máximo, a etapa 1 a encontrará (como mostrado acima) e a etapa 2 a confirmará.
- Se a entrada não contiver um elemento máximo, a etapa 1 acabará escolhendo algum elemento arbitrário como
m
. Não importa qual elemento seja, pois, em qualquer caso, não será o máximo e, portanto, a etapa 2 detectará isso e retornará None
.
Se armazenado o índice m
na matriz de entrada a
, poderíamos realmente passo otimizar 2 para verificar apenas aqueles elementos que vêm antes m
de a
, já que qualquer elementos posteriores já foram comparados com m
na etapa 1. Mas essa otimização não altera a complexidade de tempo assintótica do algoritmo, que ainda é O ( n ).