-1

私がクラスのために書いているこのプログラムは、「乱数」を使用して、ジョブの到着 (arrival[i]) とサービス時間 (service[i]) を生成します。私の現在の問題は到着時間です。到着時間を取得するには、exponential という名前の関数を呼び出し、戻り値を配列内の前回の到着時間 (arrival[i-1]) に追加します。何らかの理由で、プログラムは加算に配列の以前の値を使用していませんが、一見ランダムな値 (1500,1600 ect) を使用しています。しかし、配列に設定された実際の値がすべて 5 未満であることはわかっています。これは、for ループでの単純な配列演算である必要がありますが、何が問題なのかわかりません。

namespace ConsoleApplication4
{

class Program
{
    static long state;

    void putseed(int value)
    {
        state = value;
    }

    static void Main(string[] args)
    {
        Program pro = new Program();
        double totals = 0;
        double totald = 0;
        pro.putseed(12345);
        double[] arrival = new double[1000];
        double[] service = new double[1000];
        double[] wait = new double[1000];
        double[] delay = new double[1000];
        double[] departure = new double[1000];
        for (int i = 1; i < 1000; i++)
        {
            arrival[i] = arrival[i - 1] + pro.Exponential(2.0);
            if (arrival[i] < departure[i - 1])
                departure[i] = departure[i] - arrival[i];
            else
                departure[i] = 0;
            service[i] = pro.Uniform((long)1.0,(long)2.0);
            totals += service[i];
            totald += departure[i];
        }
        double averages = totals / 1000;
        double averaged = totald / 1000;
        Console.WriteLine("{0}\n",averages);
        Console.WriteLine("{0}\n", averaged);
        Console.WriteLine("press any key");
        Console.ReadLine();
    }

    public double Random()
    {
        const long A = 48271;
        const long M = 2147483647;
        const long Q = M / A;
        const long R = M % A;
        long t = A * (state % Q) - R * (state / Q);
        if (t > 0)
            state = t;
        else
            state = t + M;
        return ((double)state / M);
    }

    public double Exponential(double u)
    {
        return (-u * Math.Log(1.0 - Random()));
    }

    public double Uniform(long a, long b)
    {
        Program pro = new Program();
        double c = ((double)a + ((double)b - (double)a) * pro.Random());
        return c;
    }
}

}

4

4 に答える 4

1

メソッドによって返される値はExponential非常に大きくなる可能性があります。非常に大きい。実際、値が 1 に近づくと、無限大になる傾向がありますRandom...

到着配列の値が大きくなる傾向があることに驚かないでください。実際、私は彼らがそうするだろうと期待しています。

また、メソッドが何をするかに応じてメソッドに名前を付けるようにしてください。あなたのExponential方法は、数学的指数とは何の関係もありません。

また、乱数ジェネレーターを自分で実装しないようにしてください。Random.Net Framework に含まれているクラスを使用します。疑似乱数の同じシーケンスを常に保持したい場合 (必要に応じて)、定数をシードすることができます。

于 2012-11-06T15:40:17.010 に答える
1

現在のロジックを考えると、あなたの出力は私には完全に正しいように聞こえます。多分あなたの論理に欠陥がありますか?

forループの最初の 3 行を次のように変更しました。

var ex = Exponential(2.0);
arrival[i] = arrival[i - 1] + ex;
Console.WriteLine("i = " + arrival[i] + ", i-1 = " + arrival[i-1] + ", Exponential = " + ex);

そして、これは出力の開始と終了です:

i = 0.650048368820785, i-1 = 0, Exponential = 0.650048368820785
i = 3.04412645597466, i-1 = 0.650048368820785, Exponential = 2.39407808715387
i = 4.11006720700818, i-1 = 3.04412645597466, Exponential = 1.06594075103352
i = 5.05503853283036, i-1 = 4.11006720700818, Exponential = 0.944971325822186
i = 6.77397334440211, i-1 = 5.05503853283036, Exponential = 1.71893481157175
i = 8.03325406790781, i-1 = 6.77397334440211, Exponential = 1.2592807235057
i = 9.99797822010981, i-1 = 8.03325406790781, Exponential = 1.964724152202
i = 10.540051694898, i-1 = 9.99797822010981, Exponential = 0.542073474788196
i = 10.6332298644808, i-1 = 10.540051694898, Exponential = 0.0931781695828122
....
i = 1970.86834655692, i-1 = 1968.91989881306, Exponential = 1.94844774386271
i = 1971.49302600885, i-1 = 1970.86834655692, Exponential = 0.62467945192265
i = 1972.16711634654, i-1 = 1971.49302600885, Exponential = 0.674090337697884
i = 1974.5740025773, i-1 = 1972.16711634654, Exponential = 2.40688623075635
i = 1978.14531015105, i-1 = 1974.5740025773, Exponential = 3.5713075737529
i = 1979.15315663014, i-1 = 1978.14531015105, Exponential = 1.00784647908321

ここでの計算は、私には完全に正しいように見えます。


補足: すべての追加メソッド ( 、 など) を として宣言できるExponentialためUniform、それらを使用するためだけにstatic新しいメソッドを作成する必要はありませんProgram

于 2012-11-06T15:43:01.467 に答える
0

到着[0]の値を設定していません。これは、forループの前に初期化されていないため、配列内の他の値が正しく計算されていません。

于 2012-11-06T15:31:53.777 に答える
0

追加の提案、

public double Uniform(long a, long b)
{
    double c = ((double)a + ((double)b - (double)a) * Random());
    return c;
}

そのようにユニフォーム機能を変更します。

于 2012-11-06T15:40:47.410 に答える