Collatz Attack!


8

Esse desafio é baseado em algumas novas descobertas relacionadas à conjectura de Collatz e projetado de alguma forma no espírito de um projeto colaborativo de polímatas . A solução da conjectura completa é considerada extremamente difícil ou impossível pelos especialistas em matemática / teoria dos números, mas essa tarefa mais simples é bastante viável e há muitos exemplos de código de amostra. Na melhor das hipóteses, novas idéias teóricas podem ser obtidas para o problema com base nas entradas / engenhosidade / criatividade dos concorrentes.

A nova descoberta é a seguinte: Imagine uma série contígua de números inteiros [ n1 ... n2 ] digamos m total. Atribua esses números inteiros a uma estrutura de lista. Agora, uma versão generalizada da conjectura de Collatz pode prosseguir da seguinte maneira. Itere um dos m (ou menos) números inteiros na lista a seguir com base em alguns critérios / algoritmo de seleção. Remova esse número inteiro da lista se atingir 1. Claramente, a conjectura de Collatz é equivalente a determinar se esse processo sempre é bem-sucedido em todas as opções de n1, n2 .

Aqui está a torção, uma restrição adicional. Em cada etapa, adicione m atual itera na lista juntos. Em seguida, considere a função f (i) onde i é o número da iteração ef (i) é a soma das iterações atuais na lista. Procure f (i) com uma propriedade "agradável" específica.

O conceito geral / geral é melhor / mais bem documentado aqui (com muitos exemplos em ruby). A conclusão é que existem estratégias / heurísticas / algoritmos bastante simples que levam a uma "diminuição praticamente monotônica" de f (i) e muitos exemplos são dados nessa página. Aqui está um exemplo da saída gráfica (plotada via gnuplot):

Então, aqui está o desafio: use variações nos exemplos existentes ou idéias inteiramente novas para criar um algoritmo de seleção que resulte em f (i) "o mais próximo possível da redução monotônica possível". Os participantes devem incluir um gráfico de f (i) em sua inscrição. Os eleitores podem votar com base nesse gráfico e nas idéias algorítmicas do código.

O concurso será baseado apenas nos parâmetros n1 = 200 / n2 = 400 ! (o mesmo na página de exemplo.) Mas, esperançosamente, os participantes explorarão outras regiões e também tentarão generalizar seus algoritmos.

Observe que uma tática que pode ser muito útil aqui são algoritmos do tipo descida de gradiente ou algoritmos genéticos.

Pode discutir isso ainda mais no chat para os participantes interessados.

Para alguns árbitros, outro desafio de Collatz no codegolf: Collatz Conjecture (por Doorknob )


5
Letras maiúsculas por favor!
TheDoctor

1
Por que as pessoas estão votando para fechar? É bom ter perguntas não estereotipadas! Eu o problema de pensar demais / ler envolvido na compreensão da pergunta ?!
Mau

2
iterar aqui significa "avançar para o próximo 'iterar' na sequência Collatz para esse número inteiro"
vzn

1
Parece que o exemplo que você postou vai ser difícil de bater ... :)
apnorton

1
@vzn Não posso prometer uma submissão tão cedo, pois vou de férias neste fim de semana após o término das aulas, e as coisas estão meio agitadas no momento. No entanto, certamente experimentarei isso - afinal, essa é uma nova abordagem para um problema que acho muito intrigante. :)
apnorton

Respostas:


4

Eu escrevi algum código no Python 2 para executar algoritmos para este desafio:

import matplotlib.pyplot as plt

def iterate(n):
    return n*3+1 if n%2 else n/2
def g(a):
    ##CODE GOES HERE
    return [True]*len(a)
n1=input()
n2=input()
a=range(n1,n2+1)
x=[]
y=[]
i=0
while any(j>1 for j in a):
    y.append(sum(a))
    x.append(i)
    i+=1
    b=g(a)
    for j in range(len(a)):
        if b[j]:
            a[j]=iterate(a[j])
plt.plot(x,y)
plt.show()

g(x) pega a lista de valores e retorna uma lista de bools para saber se cada um deve ser alterado.

Isso inclui a primeira coisa que tentei, como a linha logo após o comentário, que estava iterando todos os valores da lista. Eu tenho esse:

Tentativa 1

Não parece nem um pouco monotônico, então tentei iterar apenas os valores que diminuiriam a soma, se houver, iterando os que aumentariam menos:

l=len(a)
n=[iterate(i) for i in a]
less=[n[i]<a[i] for i in range(l)]
if any(less):
    return less
m=[n[i]-a[i] for i in range(l)]
return [m[i]==min(m) for i in range(l)]

Infelizmente, isso não terminar (pelo menos para n1=200, n2=400). Tentei acompanhar os valores que já havia visto inicializando c=set():

l=len(a)
n=[iterate(i) for i in a]
less=[n[i]<a[i] for i in range(l)]
if any(less):
    return less
m={i:n[i]-a[i] for i in range(l)}
r=[i for i in m if m[i]==min(m.values())]
while all([a[i] in c for i in r]) and m != {}:
    m={i:m[i] for i in m if a[i] not in c}
    r+=[i for i in m.keys() if m[i]==min(m.values())]
for i in r:
    c.add(a[i])
return [i in r for i in range(l)]

Isso também não termina.

Ainda não tentei mais nada, mas se tiver novas idéias, as postarei aqui.


+1 thx pelo seu interesse e reativar o desafio. isso não é muito bom para o desempenho, mas você começa a aceitação de qualquer maneira, meu pequeno gesto de thx :) ... também outros interessados PLZ sentem livres para conversar sobre isso ou convidar-me no chat para discutir mais
vzn

2

Python 3

Minha idéia principal era adicionar cada sequência de Collatz dos números à f(i)função individualmente, de forma a minimizar o aumento total de f(i). A função resultante não está diminuindo estritamente, mas possui uma estrutura agradável (na minha opinião :)). O segundo gráfico foi criado com um intervalo maior para f(i)uma função de punição ligeiramente diferente. Código no Gist.

Collatz1 Collatz2

Ao usar a regra (3 * n + 1) / 2 em vez da regra 3 * n + 1, o algoritmo produz um método completamente monotônico f(i)! Tenho certeza de que essa modificação pode tornar os gráficos do vzn muito mais suaves também. O segundo gráfico foi criado com um intervalo maior para f(i). Código no Gist.

Collatz3 Collatz4

Ambos os resultados são semelhantes para [n,2*n]intervalos maiores .


Os dois segundos são novos / ótimos, os melhores lançamentos externos até agora! uma diminuição completamente monotônica é algo como um avanço! se você pode mostrar que ele funciona em partidas cada vez maiores, itera de "maneira semelhante", que é realmente um candidato à estratégia de prova ...!
vzn

@vzn Com algumas modificações, estritamente monotônico fparece ser possível. Mesmo que meu algoritmo atual falhe, há um espaço considerável para melhorias. Vou deixá-lo funcionar e ver se ele falha em alguns n(mais de 200). A monotonia estrita é mais forte que a conjectura de Collatz, por isso posso passar adiante por enquanto. :) Suas funções funcionam bem com a regra (3n + 1) / 2? Por que você não usa isso?
randomra

@vzn Tantas idéias ... O principal problema é o xkcd :) relevante . A diminuição monotônica parece manter-se. Um [1,n]intervalo pode ser mais interessante, porque também podemos perguntar (se a monotonia se mantém) se podemos criar um [1,n+1]não modificando o [1,n]um e adicionando a n+1sequência a ele.
Aleatório

tão bom ver alguma inspiração compartilhada! uma estratégia de prova poderia funcionar de qualquer maneira, por exemplo, em "blocos" de tamanho constante. a partir de experimentos na página citada, várias estratégias tendem a "quebrar" por n maior . descrição mais detalhada do seu algoritmo em palavras seria ótimo.
vzn

fyi portou isso para ruby ​​e fez alguns experimentos básicos, representados graficamente os resultados aqui . o código parece ter uma pequena dependência do não-determinismo, mas talvez não para n maior.
vzn
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.