Sua missão é criar um algoritmo (programa ou função) que otimize a embalagem de frutas de uma correia transportadora em sacolas para serem enviadas aos varejistas, otimizando para um maior número de sacolas.
Cada sacola deve pesar pelo menos uma certa quantia, mas qualquer excesso é perda de lucro, pois esse peso pode ser usado para encher outra sacola. Sua máquina de ensacamento sempre tem uma lista de n
frutas na fila e pode optar por adicionar qualquer uma dessas n
frutas à sacola (única) que está sendo processada. Ele não pode olhar além dos n
primeiros elementos da fila. O programa sempre sabe exatamente quanto peso já existe na sacola.
Outra maneira de visualizar isso é ter uma correia transportadora com uma área de carga de tamanho n
no final, de onde uma fruta deve ser retirada antes que uma nova fruta chegue. Qualquer fruta que sobrar e uma sacola não cheia no final são descartadas.
Entradas
- Lista / matriz de pesos de frutas na fila (números inteiros positivos)
- Peso total mínimo para sacos (número inteiro positivo)
- Lookahead
n
(número inteiro positivo)
Saída
Seu algoritmo deve retornar para todas as sacolas os pesos das frutas nelas, por qualquer meio que seja conveniente para você e seu idioma, seja stdin ou um valor de retorno ou qualquer outra coisa. Você poderá executar o programa e calcular sua pontuação em um minuto no seu computador.
Exemplo
Total weight 1000, lookahead of 3 and fruit queue:
[171,163,172,196,156,175,162,176,155,182,189,142,161,160,152,162,174,172,191,185]
One possible output (indented to show how the lookahead affects the bagging):
[171,163,172, 156,175, 176]
[162, 155,182,189, 161,160]
[152,162,174,172,191,185]
Pontuação
Seu algoritmo será testado em seis execuções em um lote de 10.000 laranjas que eu preparei para você, em viseiras que variam de 2 a 7, inclusive nas duas extremidades. Você deve embalá-los em sacos de pelo menos 1000 unidades. As laranjas são normalmente distribuídas com um peso médio de 170 e um desvio padrão de 13, se isso for de alguma ajuda.
Sua pontuação será a soma do número de malas das seis corridas. A pontuação mais alta vence. As brechas padrão não são permitidas.
Implementação de exemplo simples e clichê do conjunto de testes em Haskell
Respostas:
Python 3,
99649981 sacosA ideia desta solução é semelhante à de Jonathan, JayCe e fortraan, mas com uma função de pontuação =)
Esta solução anexa os melhores subconjuntos da área de lookahead de acordo com o
score
.score
fornece uma ordem sobre os subconjuntos usando o seguinte esquema:expected_mean
tenta prever como deve ser o restante dos valores (assumindo que a escolha é a ideal).UPD :
Aqui está outra observação: você pode colocar qualquer laranja do melhor subconjunto na bolsa sem prejudicar o desempenho do algoritmo. Mover qualquer parte dela ainda permite mover o restante depois, e o restante ainda deve ser a melhor opção (sem novas laranjas) se a pontuação estiver correta. Além disso, dessa forma, é possível melhorar dinamicamente o conjunto de candidatos a serem colocados na sacola vendo mais laranjas antes de encher a sacola. E você deseja saber o máximo de informações possível, para que não faça sentido mover mais de uma laranja para a bolsa a qualquer momento.
Tente!
fonte
powerset
função é redundante, neste caso, porque é igual alen(list_)
de qualquer maneira?)expected_mean(w)
que dá bons resultados:return (w+2) / max(1, round((w+2) / mean))
Python 3 , 9796 sacos
Com base na resposta de Jonathan:
Isso depende do conjunto de ferramentas do livro de receitas do itertool. Primeiro, encontra o subconjunto ideal do buffer com base na minimização da diferença do peso alvo para todos os subconjuntos e, em seguida, seleciona um elemento desse subconjunto com base no mesmo critério. Se nenhum subconjunto ideal seleciona o buffer inteiro.
fonte
C ++ 17, 9961,58 (média de algumas sementes aleatórias)
(role para baixo para obter uma explicação se você não conhece C ++)
(se
<
for usado basicamente, o algoritmo tenta minimizar o número de malas)Inspirado por esta resposta .
Link TIO para 250 repetições: Experimente online!
Define uma função (na verdade, apenas se parece com uma função, é uma estrutura)
pick_orange
que, dadovector<int> weights
o peso das laranjas eint remain
o peso restante da sacola, retorna o índice da laranja que deve ser colhida.Algoritmo:
os
500
tempos de repetição{
geram laranjas aleatórias (falsas) (distribuição normal com média 170 e stddev 13) até que
N_NEW_ORANGES=7
laranjasselecionem qualquer subconjunto cuja soma seja menor e não menor que
remain
(a funçãobacktrack
faz isso)marcar todas as laranjas nesse subconjunto como boas
}
calcule a média do número de vezes que as laranjas marcadas como boas das laranjas (reais) com peso igual
retornam a melhor laranja
Existem 3 constantes codificadas no programa que não podem ser deduzidas do problema:
N_NEW_ORANGES
(o comprimento da previsão). Aumentar isso faz com que o programa seja executado exponencialmente mais (porque retrocede)fonte
invalid use of template-name ‘std::normal_distribution’
. Sem problemas com o gcc 7.1.0.Python 2 , 9756 sacos
Vamos fazer a laranja rolar ...
Experimente online!
Sempre escolhe a fruta do buffer, o que minimiza a diferença absoluta do novo peso e do peso alvo.
fonte
Python 3, 9806 sacos
Com base nas respostas de Jonathan e JayCe:
Experimente online!
Como funciona
Digamos que a bolsa tenha 900 unidades e há 2 frutas disponíveis: uma fruta de 99 unidades e uma fruta de 101 unidades. Se o fruto de 99 unidades estiver mais próximo do início da lista de procura,
min
selecioná-lo-á em vez de 101. Se isso acontecer, precisaríamos agora de outro fruto para atender a 1 unidade restante necessária. Mudei o programa para favorecer os frutos de maior valor nesses casos.Isso é feito classificando e revertendo a lista de visualizadores de objetos antes de definir a potência.
fonte
PHP, 9975 sacolas
mais longo de todos os envios, mas deve ser legível
Tente
fonte
Python 3,
98559928994799569964 sacosBaseado no código de partida de Jonathan Allan, mas sem o poder de ser legível.
Idéia: Como 1000/170 = 5,88, tentamos selecionar frutas próximas a 1000/6 (eu brinquei com as constantes mágicas). No entanto, se a última fruta na bolsa puder minimizar o desperdício, nós a usaremos.
Esta solução possui metas de soma de sacos para cada fruta adicionada. Provavelmente vou parar por aqui. Usei o Nelder-Mead para encontrar minha
targets
matriz:9956 sacos
O programa 9947 bags é particularmente simples:
fonte
targets
? Treinamento em dados aleatórios?Ruby , 9967 sacos
Experimente online!
Se você tiver peso suficiente para encher o saco, encontre o subconjunto mais leve que possa encher o saco e use a laranja mais clara desse subconjunto. Caso contrário, obtenha o peso restante o mais próximo possível de um múltiplo de 170.
fonte
Raquete / esquema, 9880 sacos
Para decidir qual peça de fruta adicionar à sacola, compare o peso ideal da sacola com o peso da sacola com a peça adicional de fruta. Se for o peso ideal, use-o. Se estiver acima do peso, minimize a quantidade em excesso. Se estiver abaixo do peso, minimize a quantidade excessiva depois de tentar deixar um espaço ideal.
fonte
Haskell , 9777 bolsas
Esta foi minha primeira tentativa:
Experimente online!
fonte
Haskell , 9981 bolsas
O Angs → Jonathan Allan → JayCe → fortraan → Alex → Roman Czyborra codegolf python poderia pedalar de volta a Haskell para obter alguma pureza matemática adicional ao longo da mesma linha principal de pensamento
(<miss)==False<True
)para esse número inteiro, inverta a
(m-n)/sqrt(n)==(n+1-m)/sqrt(n+1) <==> n=sqrt(m^2-1/4)-1/2
partir de https://en.wikipedia.org/wiki/Sum_of_normally_distributed_random_variablestemperado com algumas inutilidade desnecessárias
Experimente online!
sem gerar um ganho numérico diferente no topo das 9981 redes de laranjas colhidas antes, enquanto meu empacotador de sacolas 10k011 que pegava laranjas impróprias de volta de sacolas não fechadas foi desqualificado por user69850 na persona user202729 → Jo King → portanto, a recompensa merecida foi para Alex
fonte