0

1 つのリストからランダムな値を取得し、それらを多次元配列に配置する次のコードがあります。これを使用して PDF を作成します。

protected void ConstruirExamenesAndGenerarPdf(int[] idUnidades, int numeroExamenes, int numeroReactivos)
{
    var modeloReactivos   = new ModeloReactivos();
    var reactivosUnidades = modeloReactivos.ObtenerReactivosPorIdsUnidades(idUnidades);

    var examenes = ConstruirExamenes(reactivosUnidades, numeroExamenes, numeroReactivos);

    GenerarPdf(examenes, reactivosUnidades);
}


private int[][] ConstruirExamenes(List<Reactivo> reactivosUnidades, int numeroExamenes, int numeroReactivos)
{
    var cantidadObligatorios   = reactivosUnidades.Where(r => r.obligatorio == (byte)Reactivo.Obligatoria.Si).Count();
    var cantidadNoObligatorios = reactivosUnidades.Where(r => r.obligatorio == (byte)Reactivo.Obligatoria.No).Count();

    var indicesObligatorios   = Enumerable.Range(0, cantidadObligatorios - 1).ToArray();
    var indicesNoObligatorios = Enumerable.Range(indicesObligatorios.Length, cantidadNoObligatorios - 1).ToArray();

    var examenes = new int[numeroExamenes][];

    for (var indiceExamen = 0; indiceExamen < numeroExamenes; indiceExamen++)
    {
        examenes[indiceExamen] = ConstruirExamen(indicesObligatorios, indicesNoObligatorios, numeroReactivos);
    }

    return examenes;
}

protected int[] ConstruirExamen(int[] indicesObligatorios, int[] indicesNoObligatorios, int numeroReactivos)
{
    var examen = new List<int>();

    AgregarReactivosAleatorios(examen, indicesObligatorios, numeroReactivos);
    AgregarReactivosAleatorios(examen, indicesNoObligatorios, numeroReactivos);

    return examen.ToArray();
}

private static void AgregarReactivosAleatorios(List<int> examen, int[] indicesReactivos, int numeroReactivos)
{

    var random = new Random();
    var actual = indicesReactivos.Length;

    for (var i = examen.Count; i < numeroReactivos && i < indicesReactivos.Length; i++)
    {
        var indexReactivoSeleccionar = random.Next(actual);

        var agregarEn = random.Next(0, examen.Count + 1);

        examen.Insert(agregarEn, indicesReactivos[indexReactivoSeleccionar]);

        indicesReactivos[indexReactivoSeleccionar] = indicesReactivos[--actual];
        indicesReactivos[actual]                   = examen[agregarEn];
    }
}

デバッグ中に、pdf を生成する直前にブレークポイントを設定して配列を調べると、次のようになります。

[ [1,15,42,58],
  [8,9,52,69],
  [1,15,42,58],
  [8,9,52,69] ]

行 1 と 3 が等しいことに注意してください。行 2 と 4 も同様です。ベクトルが作成されるたびにブレークポイントを配置すると、値が繰り返されないように見えます。これは何が原因ですか?

4

1 に答える 1

1

メソッドが数回呼び出される場合は、メソッドでRandomインスタンスを作成しないでください。単一のRandomインスタンスを使用します。その理由はRandom、既定のコンストラクターを使用して立て続けに のインスタンスを複数作成すると、それらのインスタンスが同じシードを持つことになり、同じ乱数列が生成されるためです。

于 2013-04-01T10:01:47.753 に答える