Esse problema surgiu no teste de software. O problema é um pouco difícil de explicar. Primeiro darei um exemplo, depois tentarei generalizar o problema.
Existem 10 itens a serem testados, digamos A a J, e uma ferramenta de teste que pode testar 3 itens ao mesmo tempo. A ordem dos itens na ferramenta de teste não importa. Obviamente, para testes exaustivos, precisamos de combinações de itens.
O problema é mais complexo. Há uma condição adicional de que, uma vez que um par de itens tenha sido testado juntos, o mesmo par não precise ser testado novamente.
Por exemplo, uma vez que executamos os três testes a seguir:
abc
ADE
BDF
não precisamos executar:
ABD
porque o par A, B foi coberto pelo primeiro caso de teste, A, D foi coberto pelo segundo e B, D foi coberto pelo terceiro.
Portanto, o problema é: qual é o número mínimo de casos de teste que precisamos para garantir que todos os pares sejam testados?
Para generalizar, se tivermos n itens, s podem ser testados ao mesmo tempo e precisamos garantir que todas as t tuplas possíveis sejam testadas (como s> t), qual é o número mínimo de casos de teste que precisamos em termos de n, s e t?
E, finalmente, qual seria um bom algoritmo para gerar os casos de teste necessários?
fonte
Respostas:
Os projetos de bloco que você deseja (para testar três itens de cada vez e cobrir todos os pares) são chamados de sistemas triplos Steiner . Existe um sistema triplo Steiner com tripla sempre que mod , e são conhecidos algoritmos para construí-los. Veja, por exemplo, esta pergunta do MathOverflow (com um link para trabalhar com o código Sage!). Para outros , você pode arredondar para o próximo mod e usar uma modificação desse sistema triplo para para cobrir todos os pares para .13(n2) n≡1 or 3 6 n n′≡1 or 3 6 n′ n
Se você deseja a melhor construção para outros , o número de triplos necessário é o número de cobertura e é fornecido por esta entrada na enciclopédia on-line de sequências inteiras. Isso está relacionado ao Repositório de Coberturas de La Jolla, que possui um repositório de boas coberturas. A enciclopédia on-line de seqüências inteiras fornece uma fórmula conjecturada para ; se essa fórmula é válida, intuitivamente, isso significa que provavelmente deve haver boas maneiras algorítmicas de construir essas coberturas, mas, como a fórmula é conjecturada, fica claro que atualmente ninguém as conhece.n C(n,3,2) C(n,3,2)
Para números de cobertura altos, é mais difícil encontrar boas coberturas do que para , e o repositório fornecerá soluções melhores do que qualquer algoritmo eficiente conhecido.C(n,3,2)
fonte
Forme o gráfico não direcionado onde cada vértice é um par de itens e onde existe uma aresta entre dois vértices se eles compartilham um item em comum. Em outras palavras, onde e . O gráfico tem vértices e todos os vértices têm arestas incidentes.G G=(V,E) V={{a,b}:a,b∈Items∧a≠b} E={(s,t):s,t∈V∧|s∩t|=1} (n2) 2n−4
Em seguida, uma abordagem seria encontrar uma correspondência máxima em . O algoritmo de Edmonds pode ser usado para encontrar uma correspondência máxima no tempo polinomial. Se você tiver sorte, isso lhe dará uma combinação perfeita e você será bom. Cada aresta na correspondência corresponde a um caso de teste . Como todo vértice é incidente com uma aresta na combinação perfeita, você cobriu todos os pares, usando casos de teste, que estão dentro de um fator do ideal. Se você não conseguir uma correspondência perfeita, adicione mais alguns casos de teste, conforme necessário, para obter uma cobertura completa.G ({A,B},{B,C})∈E ABC (n2)/2 1.5
fonte
No caso da e é necessário realizar pelo menos testes, uma vez que existem pares e cada tampas de teste 3 pares. Isso significa que você pode fazer o que é trivial e executar testes e ser apenas um fator 3 pior que o ideal.s=3 t=2 (n2)/3 (n2) (n2)
Se você está realmente programando isso, então uma maneira de otimizar isso pode ser escolher alguns testes numéricos aleatoriamente e, em seguida, fazer a força bruta nos pares não cobertos pelo teste até agora.
Para geral e , existe um limite inferior de testes. Para um limite superior, estou afirmando que isso é suficiente para fazer com que testes.s t (nt)/(st) C⋅(nt)(st)⋅log((nt))≤O(t⋅(n−ts−t)tlog(n))
Vamos ver o que acontece, nós escolhemos os testes uniformemente aleatoriamente. Se você escolher um -tuple aleatoriamente, então, para um -uple fixo , temos . Portanto, se escolhermos testes aleatoriamente, entãos S⊆[n] t X⊆[n] Pr[X⊂S]=(n−ts−t)(ns) C⋅(nt)⋅log((nt))
Portanto, pelo limite de união, após testes aleatórios de todos os tples serão cobertos.O(t⋅(n−ts−t)tlog(n)) t
fonte