Esempio n. 1
0
        /// <summary>
        /// Executes a search on the provided microgrid data to generate
        /// optimal unit states for the formulated Unit Commitment Problem
        /// (UCP).
        /// </summary>
        /// <param name="input">Microgrid input data.</param>
        /// <param name="options">Defines the parameters for the PSO algorithm.</param>
        /// <param name="p_target">The local power demand at every moment of time.</param>
        /// <param name="progressCallback">Callback invoked every time the algorithm finishes a new iteration.</param>
        /// <returns>Binary integer array of unit states.</returns>
        public static async Task <int[, ]> UCPSearch(
            MGInput input,
            Options options,
            float[] p_target,
            OnNewSnapshotCallback progressCallback)
        {
            // Execute the PSO search.
#if !UNITY_WEBGL || (UNITY_WEBGL && UNITY_SSM_WEBGL_THREADING_CAPABLE)
            var t = new Task <int[]>(() =>
            {
                return(UCPExecutePSORuns(
                           input,
                           options,
                           p_target,
                           progressCallback));
            });

            t.Start();
            int[] u_thr_step_1d = await t;
#else
            int[] u_thr_step_1d = UCPExecutePSORuns(
                input,
                options,
                p_target,
                progressCallback);
#endif

            // Map the results from a 1D array to a 2D array where one
            // dimension is the generator states and the other dimension is
            // time, measured in time steps.
            int[,] u_thr_step_2d = MGHelper.Int1DToBin2D(
                u_thr_step_1d,
                options.stepCount,
                input.genCount);

            // Translate the time dimension from time steps to real time.
            float stepSize = input.tCount / options.stepCount;
            int[,] u_thr = MGHelper.TranslateTimeStep(
                u_thr_step_2d,
                stepSize,
                input.tCount,
                input.genCount);

            return(u_thr);
        }
Esempio n. 2
0
        private static int[] UCPExecutePSORuns(
            MGInput m,
            Options o,
            float[] p_target,
            OnNewSnapshotCallback progressCallback)
        {
            Random random = o.randomSeed.HasValue
                ? new Random(o.randomSeed.Value)
                : new Random();

            int runCount  = o.runCount;
            int iterCount = o.iterCount;
            int pCount    = o.particleCount;
            int stepCount = o.stepCount;
            int stepSize  = m.tCount / stepCount;

            int[] rBest        = new int[stepCount];
            float rBestFitness = float.MaxValue;
            float totalIter    = runCount * iterCount;
            var   threads      = new Thread[runCount];
            var   results      = new PSOResult[runCount];

            Dictionary <StateStep, float> cDict;

            cDict = MGHelper.ConstructCostDictionary(m, stepCount, stepSize, 400.0f, p_target);

            // Precompute an array that maps generator indices to the operating
            // costs for that generator if it ran at maximum power for a
            // timestep.
            float[] c_thr_max_1m = MGHelper.ThermalGenerator.GetCostAtMaxPower(
                m.genCount,
                m.p_thr_max,
                m.thr_c_a,
                m.thr_c_b,
                m.thr_c_c,
                stepSize);

            var lockObject     = new object();
            var iterLatest     = new int[runCount];
            var progressPerRun = new IterationSnapshot[runCount, iterCount];

            for (int iRun = 0; iRun < runCount; iRun++)
            {
                iterLatest[iRun] = -1;
            }

            void progressInner(
                int runIndex,
                int iterIndex,
                IterationSnapshot progressStruct)
            {
                lock (lockObject)
                {
                    iterLatest[runIndex] = iterLatest[runIndex] < iterIndex
                        ? iterIndex
                        : iterLatest[runIndex];

                    progressPerRun[runIndex, iterIndex] = progressStruct;

                    progressCallback?.Invoke(
                        runIndex,
                        iterIndex,
                        (int[])iterLatest.Clone(),
                        (IterationSnapshot[, ])progressPerRun.Clone());
                }
            }

#if !UNITY_WEBGL || (UNITY_WEBGL && UNITY_SSM_WEBGL_THREADING_CAPABLE)
            // Run the PSO multiple times in parallel.
            for (int iRun = 0; iRun < runCount; iRun++)
            {
                int _iRun = iRun;
                threads[_iRun] = new Thread(() =>
                {
                    var r          = random.Next();
                    results[_iRun] = UCPExecutePSORun(
                        _iRun, m, o, r, p_target, c_thr_max_1m, cDict, progressInner);
                });

                threads[_iRun].IsBackground = true;
                threads[_iRun].Start();
            }

            for (int iRun = 0; iRun < threads.Length; iRun++)
            {
                threads[iRun].Join();
            }
#else
            for (int iRun = 0; iRun < runCount; iRun++)
            {
                var r = random.Next();
                results[iRun] = UCPExecutePSORun(
                    iRun,
                    m,
                    o,
                    r,
                    p_target,
                    c_thr_max_1m,
                    cDict,
                    progressInner);
            }
#endif


            // Pick the best run.
            for (int iRun = 0; iRun < runCount; iRun++)
            {
                PSOResult result = results[iRun];
                if (result.bestFitness < rBestFitness)
                {
                    rBestFitness = result.bestFitness;
                    Array.Copy(result.bestPos, rBest, stepCount);
                }
            }

            return(rBest);
        }