« Validador TD-REDF “Tipo de registro incorreto - Arquivo não UTF8″ | Home | Como utilizar o LockBox para gerar EAD / CAT-52 / Delphi »
Arranjo simples - Código delphi - Parte 2
By Paulo (CincoBytes) | January 26, 2008
Este artigo é a seqüência do publicado no dia 12 de Janeiro… de lá para cá consegui algum tempo livre e melhorei o algoritmo obtendo um redução de 55% no tempo de processamento conforme descrito abaixo:
As(10,7) = 604.800 combinações (em um P4 1.8Ghz 512MB + Turbo Delphi)
Algoritmo anterior: ~ 1850ms (327.000 combinações/seg)
Algoritmo atual: ~ 833ms (730.000 combinações/seg)
Sobre o algoritmo
Após observar o resultado de um As(5,5) percebi que cada bloco de arranjos (determinados por seu primeiro elemento) se repetia nos próximos blocos apenas com deslocamento do elemento eleito para a esquerda. Assim sendo, notei que não há a necessidade de calcular todas a combinações, mas apenas as combinações do primeiro bloco; depois é só repetir e substituir!
ABCDE
ABCED
ABDCE
…
BACDE
BACED
BADCE
…
CABDE
CABED
CADBE
…
Segue o código…
procedure Arranjo(Elementos: string; Tamanho: integer);
var
i, j, k, nElementos, posicao, tArranjos, maximo: integer;
coluna, repeticoes, pElemento: integer;
cElementos: string;
arranjo: array of string;
bloco: array of array of string;
begin
nElementos := length(elementos);
j := 1;
for i := 1 to nElementos do
j := j * i;
k := 1;
for i := 1 to (nElementos - tamanho) do
k := k * i;
tArranjos := j div k;
SetLength(arranjo, tArranjos);
SetLength(bloco, nElementos, nElementos);
for i := 0 to nElementos - 1 do
begin
cElementos := Elementos[i + 1] +
StringReplace(Elementos, Elementos[i + 1], '', [rfReplaceAll]);
for j := 0 to nElementos - 1 do
bloco[i, j] := cElementos[j + 1];
end;
repeticoes := tArranjos;
maximo := tArranjos div nElementos;
for coluna := 0 to tamanho - 1 do
begin
posicao := 0;
cElementos := elementos;
repeticoes := repeticoes div (nElementos - coluna);
while posicao < maximo do
begin
if pos(cElementos[1], arranjo[posicao]) = 0 then
begin
pElemento := pos(cElementos[1], elementos) - 1;
for j := 0 to nElementos - 1 do
for i := posicao to posicao + repeticoes - 1 do
begin
k := i + j * maximo;
arranjo[k] := arranjo[k] + bloco[j, pElemento];
end;
posicao := posicao + repeticoes;
cElementos := copy(cElementos, 2, nElementos);
if length(cElementos) = coluna then
cElementos := elementos;
end
else
cElementos := copy(cElementos, 2, nElementos) +
cElementos[1];
end;
end;
// Usar o array como quiser //
end;
Ver: Arranjo simples - Código delphi - Parte 1…
Um abraço a todos…
May 3rd, 2008 at 9:52 pm
Em sua função falta acumular os valores nos primeiros loops [ex: j := j * i; = j:= j + (j*1)]
senão os valores retornados serão sempre nulos na hora de dividir.
May 4th, 2008 at 8:59 pm
Os loops a que você se refere estão codificados da maneira *correta* e são utilizados determinar o numero total de arrajos; obtido através do calculo
do fatorial pela formula: n!/(n-k)! (da linha 9 a 16). Obrigado enviar um comentário.
June 9th, 2008 at 12:10 am
Valewwwwwwwwwwwwwwwwwwwww!
Esse algoritmo ai salvou minha vida UAHuahuAHUA
Estou implementando o problema do caixeiro viajante pelo método da força bruta para um trabalho da faculdade e no caso dele precisaria fazer todas as possibilidades possíveis, e como estou meio sem tempo, esse código veio na hora certa.
Só queria deixar meus agradecimentos, brigadão.
\o/
November 1st, 2008 at 6:24 pm
Boas Paulo, geralmente codifico em C. De uma forma geral percebi o teu código, mas não conheço estas funções nas linhas do código. Agradecia que me digas o que fazem.
SetLength(Arranjo, TotalArranjos);
pos(ListaElementos[1], Arranjo[Posicao]) = 0
copy(ListaElementos, 2, NumeroElementos);
ou o que seria o código em C.
Obrigado,
Abraço
November 4th, 2008 at 7:14 am
Boas,
O código esta em pascal/delphi.
- SetLength, redimensiona o tamanho do array Arranjo.
- pos(ListaElementos[1], Arranjo[Posicao]) = 0
Pos informa se ListaElementos[1] existe em Arranjo[Posicao], se = 0 é porque não existe.
- copy(ListaElementos, 2, NumeroElementos)
copia o NumeroElementos da ListaElementos
a partir da posição 2.
Quanto a converter para “C” infelizmente eu não sei fazer pois não domino esta linguagem.
[]’s
November 7th, 2008 at 5:04 pm
Paulo Obgrigado pelo escalrecimento. O teu raciocínio para o cáculo dos arranjos e a tua obs da repetição dos blocos é revela inteligência. TKS