Implémentation naïve en C#. L'idée est de créer toutes les permutations possibles du tableau initial et de les énumérer. Ensuite, nous construisons une matrice des changements d'état possibles. En multipliant la matrice par elle-même N fois, on obtient la matrice montrant combien de chemins existent qui mènent de la permutation #i à la permutation #j en N étapes. L'élément [0,0] montrera combien de chemins mèneront au même état initial. La somme des éléments de la ligne 0 indique le nombre total de chemins différents. En divisant le premier par le second, on obtient la probabilité.
En fait, le nombre total de permutations est N^(2N).
Output:
For N=1 probability is 1 (1 / 1)
For N=2 probability is 0.5 (8 / 16)
For N=3 probability is 0.1851851851851851851851851852 (135 / 729)
For N=4 probability is 0.068359375 (4480 / 65536)
For N=5 probability is 0.0193664 (189125 / 9765625)
For N=6 probability is 0.0057198259072973293366526105 (12450816 / 2176782336)
class Program
{
static void Main(string[] args)
{
for (int i = 1; i < 7; i++)
{
MainClass mc = new MainClass(i);
mc.Run();
}
}
}
class MainClass
{
int N;
int M;
List<int> comb;
List<int> lastItemIdx;
public List<List<int>> combinations;
int[,] matrix;
public MainClass(int n)
{
N = n;
comb = new List<int>();
lastItemIdx = new List<int>();
for (int i = 0; i < n; i++)
{
comb.Add(-1);
lastItemIdx.Add(-1);
}
combinations = new List<List<int>>();
}
public void Run()
{
GenerateAllCombinations();
GenerateMatrix();
int[,] m2 = matrix;
for (int i = 0; i < N - 1; i++)
{
m2 = Multiply(m2, matrix);
}
decimal same = m2[0, 0];
decimal total = 0;
for (int i = 0; i < M; i++)
{
total += m2[0, i];
}
Console.WriteLine("For N={0} probability is {1} ({2} / {3})", N, same / total, same, total);
}
private int[,] Multiply(int[,] m2, int[,] m1)
{
int[,] ret = new int[M, M];
for (int ii = 0; ii < M; ii++)
{
for (int jj = 0; jj < M; jj++)
{
int sum = 0;
for (int k = 0; k < M; k++)
{
sum += m2[ii, k] * m1[k, jj];
}
ret[ii, jj] = sum;
}
}
return ret;
}
private void GenerateMatrix()
{
M = combinations.Count;
matrix = new int[M, M];
for (int i = 0; i < M; i++)
{
matrix[i, i] = N;
for (int j = i + 1; j < M; j++)
{
if (2 == Difference(i, j))
{
matrix[i, j] = 2;
matrix[j, i] = 2;
}
else
{
matrix[i, j] = 0;
}
}
}
}
private int Difference(int x, int y)
{
int ret = 0;
for (int i = 0; i < N; i++)
{
if (combinations[x][i] != combinations[y][i])
{
ret++;
}
if (ret > 2)
{
return int.MaxValue;
}
}
return ret;
}
private void GenerateAllCombinations()
{
int placeAt = 0;
bool doRun = true;
while (doRun)
{
doRun = false;
bool created = false;
for (int i = placeAt; i < N; i++)
{
for (int j = lastItemIdx[i] + 1; j < N; j++)
{
lastItemIdx[i] = j; // remember the test
if (comb.Contains(j))
{
continue; // tail items should be nulled && their lastItemIdx set to -1
}
// success
placeAt = i;
comb[i] = j;
created = true;
break;
}
if (comb[i] == -1)
{
created = false;
break;
}
}
if (created)
{
combinations.Add(new List<int>(comb));
}
// rollback
bool canGenerate = false;
for (int k = placeAt + 1; k < N; k++)
{
lastItemIdx[k] = -1;
}
for (int k = placeAt; k >= 0; k--)
{
placeAt = k;
comb[k] = -1;
if (lastItemIdx[k] == N - 1)
{
lastItemIdx[k] = -1;
continue;
}
canGenerate = true;
break;
}
doRun = canGenerate;
}
}
}
9 votes
Pour un
N
et une graine fixe, la probabilité est soit0
o1
parce que ce n'est pas du tout aléatoire.1 votes
Est-ce la réponse qu'ils attendent ? Ou veulent-ils une analyse mathématique supposant de "vraies" variables aléatoires ?
0 votes
@Mysticial : Je suis presque sûr que la graine n'est pas supposée être fixée...
0 votes
Ou peut-être voulaient-ils juste voir si vous étiez capable de penser différemment...
0 votes
@Aashish : Pouvez-vous supposer
N
est égale, juste pour des raisons de simplicité ? (Mais peut-être que cela n'aidera pas du tout, je ne suis pas sûr...)0 votes
@Mehrdad, Pourquoi même ? Est-ce que le fait de supposer que N est pair va nous aider à résoudre le problème ?
1 votes
Quelle est l'implémentation pour
swap()
? Cela pourrait être un exercice pour ne pas se fier aux noms pour leur valeur nominale.0 votes
Postez votre idée sur le N pair. Nous la généraliserons.
1 votes
(Je travaille sur l'idée, je la posterai ici si j'ai quelque chose d'utile.) Au fait, vous pouvez regarder sur Fisher-Yates Je pense que c'est ce qu'ils ont essayé d'obtenir, c'est-à-dire qu'ils ne s'attendaient pas à ce que vous obteniez la probabilité exacte, mais que vous reconnaissiez le fait qu'il s'agit d'un algorithme de brassage biaisé.
0 votes
Ici, à chaque fois, les numéros sont générés de 0 à N-1. Le mélange de Fischer Yates est différent.
0 votes
@Aashish : Je connaître Fisher-Yates est différent, c'est exactement pourquoi je l'ai mentionné ! "Ils ne s'attendaient peut-être pas à ce que vous obteniez la probabilité exacte, mais à ce que vous reconnaissiez le fait qu'il s'agit d'un algorithme de brassage biaisé."
1 votes
Ils posent cette question parce qu'ils ne veulent pas cette chose de se reproduire.
0 votes
Je veux savoir ce que le fait de connaître cette réponse a à voir avec le travail pour lequel vous avez postulé.
25 votes
S'il s'agit bien d'un programme C (comme le suggèrent les balises), la probabilité est de 1. Les éléments du tableau sont passés par valeur (il n'y a pas de passage par référence en C), donc la fonction
swap
ne peut pas modifier le contenu deA
. \edit : Eh bien,swap
pourrait être une macro aussi bien espérons que ce n'est pas le cas :)13 votes
@reima : c'est peut-être une macro.
1 votes
@reima : écrire une fonction C avec le prototype "swap(int, int)" est un mauvais style de codage puisqu'une telle fonction ne peut pas faire ce que l'on attend de son nom. Nous pouvons donc multiplier la probabilité que le tableau change par la probabilité d'avoir une macro ici (qui est quelque chose comme 99% :)
0 votes
@Aashish, le fait que N soit pair ou impair est important, non ? Disons que N est pair = 4 . Si vous m=1, n=3 pour i=0, il devrait y avoir un n=1, m=3 dans l'un des i=1,2,3. ce qui implique que vous voulez que N soit pair pour cette connexion, Si N est impair, vous devez ajouter la probabilité que pour i=k, k étant 0 à N-1, m=n, le reste de la logique étant la même que pour N est pair.
0 votes
Est-ce que nous supposons que
rand()
est censé être une distribution uniforme ? Est-elle mise en œuvre en utilisant%
et ne souffre-t-il pas d'un léger biais en faveur des petits nombres ?0 votes
Je pense que nous avons supposé que rand() choisissait chaque nombre avec une probabilité uniforme.
1 votes
Je pense que les réponses sont trop éloignées d'une solution analytique même pour le cas uniforme, donc je préfère ne pas être trop fantaisiste.
0 votes
J'ai enlevé le tag c parce qu'il n'y a absolument rien dans le problème lui-même qui dit que ça doit être en C.
0 votes
@BurhanKhalid voir ma réponse, répondre à cette question montre que le candidat est capable de pensez à .
4 votes
Pensez à demander sur math.stackexchange.com. Une reformulation : étant donné a_i, b_i aléatoires, quelle est la probabilité que la permutation (a_1 b_1) (a_2 b_2) ... (a_n b_n) = identité dans le groupe symétrique S_n ?
1 votes
Vous pourriez trouver cela intéressant : code.google.com/codejam/contest/dashboard?c=975485#s=a&a=3
1 votes
Tout d'abord, il faut se demander ce que signifie "rester le même". Le calcul le plus simple concerne le cas où aucune modification n'est apportée à aucun moment. Cela devient plus compliqué si l'on se soucie uniquement de savoir si le tableau est dans le même ordre à la fin qu'au début,
11 votes
Euh... personne n'a relevé le fait que A n'est JAMAIS INITIALISÉ ?
0 votes
@KenBeckett C'est exactement ce que je pensais, en supposant qu'il ne s'agit pas simplement d'un code simplifié.
0 votes
Je n'ai pas le temps de l'analyser pour le moment, mais cela pourrait-il être résolu par Induction mathématique sur N ?