Пример #1
0
        static void Main(string[] args)
        {
            string inputDirectory = @"C:\CSSLWaferFab\Input\WSC2021paper";

            string outputDirectory = @"C:\CSSLWaferFab\Output\WaferAreaOptimiser";

            ReaderWriter readerWriter = new ReaderWriter(inputDirectory, outputDirectory);

            Dictionary <string, Tuple <double, double> > realQueueLengths = readerWriter.GetRealQueueLengths();

            List <string> workCenters = realQueueLengths.Keys.ToList(); // All work centers

            workCenters = new List <string>()                           // Remove to evaluate all work centers
            {
                "PHOTOLITH", "DRY ETCH"
            };

            foreach (string workCenter in workCenters)
            {
                #region Parameters
                // Model parameters
                string wc = workCenter;

                DateTime initialDateTime  = new DateTime(2019, 6, 1);
                string   eptParameterFile = @"FittedEPTParameters - 2019-06-01.csv";

                bool useInitialLots = true;

                Settings.WriteOutput = false;

                // Simulated annealing parameters
                double temp = 25;

                double cooldown = 0.993; //0.995 = 1102 solutions, 0.996 = 1378 solutions, 0.997 = 1834 solutions

                double meanObj = realQueueLengths[wc].Item1;

                double stdObj = realQueueLengths[wc].Item2;

                // Dictionary with parameters to optimise and optional weights
                Dictionary <string, Parameter> parameterConfiguration = new Dictionary <string, Parameter>()
                {
                    { "LBWIP", new Parameter("LBWIP", false) },
                    { "UBWIP", new Parameter("UBWIP", false) },
                    { "Tmin", new Parameter("Tmin", false) },
                    { "Tmax", new Parameter("Tmax", true) },
                    { "Tdecay", new Parameter("Tdecay", true) },
                    { "Cmin", new Parameter("Cmin", true) },
                    { "Cmax", new Parameter("Cmax", true) },
                    { "Cdecay", new Parameter("Cdecay", true) }
                };
                #endregion

                #region Variables and instances
                Optimiser optimiser = new Optimiser(wc, temp, parameterConfiguration);

                optimiser.SetBounds(inputDirectory);

                WaferAreaSim waferAreaSim = new WaferAreaSim(wc, eptParameterFile, inputDirectory, outputDirectory, initialDateTime, optimiser, useInitialLots);

                Dictionary <string, Distribution> currentPar, nextPar, bestPar;

                Tuple <double, double> currentRes, nextRes, bestRes;

                double currentCost, nextCost, bestCost, deltaCost;

                Dictionary <WIPDepDistParameters, Tuple <double, double> > results = new Dictionary <WIPDepDistParameters, Tuple <double, double> >(); // Save all solutions

                UniformDistribution uDist = new UniformDistribution(0, 1);
                #endregion

                #region Simulated annealing algorithm
                // Initial model parameters and results
                currentPar = waferAreaSim.InitialParameters;
                bestPar    = optimiser.CopyParameters(currentPar);

                currentRes = waferAreaSim.RunSim(currentPar);
                bestRes    = optimiser.CopyResults(currentRes);

                currentCost = Math.Abs(currentRes.Item1 - meanObj) + 0.5 * Math.Abs(currentRes.Item2 - stdObj);
                bestCost    = currentCost;

                optimiser.AddResult(results, currentPar, currentRes);

                // Iterate and evaluate solutions until sufficiently cooled down
                int i = 0;
                while (temp > 0.1 && currentCost > Math.Min(1, 0.1 * (meanObj + stdObj))) // If a good solution is found, stop searching
                {
                    nextPar = optimiser.GenerateNeighbour(currentPar, temp);
                    nextRes = waferAreaSim.RunSim(nextPar);

                    nextCost = Math.Abs(nextRes.Item1 - meanObj) + 0.5 * Math.Abs(nextRes.Item2 - stdObj);

                    optimiser.AddResult(results, nextPar, nextRes);

                    if (nextCost < currentCost) // New solution is better than current, accept new solution
                    {
                        currentPar  = optimiser.CopyParameters(nextPar);
                        currentRes  = optimiser.CopyResults(nextRes);
                        currentCost = nextCost;

                        if (nextCost < bestCost) // New solution is better best, accept new best solution
                        {
                            bestPar  = optimiser.CopyParameters(nextPar);
                            bestRes  = optimiser.CopyResults(nextRes);
                            bestCost = nextCost;
                        }
                    }
                    else
                    {
                        deltaCost = nextCost - currentCost;

                        if (uDist.Next() < Math.Pow(Math.E, -deltaCost / temp)) // Accept solution if u ~ U[0,1] < e^-(dC/T)
                        {
                            currentPar  = optimiser.CopyParameters(nextPar);
                            currentRes  = optimiser.CopyResults(nextRes);
                            currentCost = nextCost;
                        }
                    }

                    temp = temp * cooldown; // Reduce temperature
                    i++;

                    Console.WriteLine("\nResults for area {0}.", wc);
                    Console.WriteLine("Iteration: {0}. Temperature {1}", i, temp);
                    Console.WriteLine("Evaluated solution: {0}, {1}", nextRes.Item1, nextRes.Item2);
                    Console.WriteLine("Current solution:   {0}, {1}", currentRes.Item1, currentRes.Item2);
                    Console.WriteLine("Best solution:      {0}, {1}\n", bestRes.Item1, bestRes.Item2);
                }
                #endregion

                #region Write results to file
                // Write all results to a text file
                readerWriter.WriteAllSolutions(results, wc);

                // Write the best and current solution to a text file
                readerWriter.WriteFinalSolutions(currentPar, currentRes, bestPar, bestRes, wc);
                #endregion
            }
        }
Пример #2
0
        public Dictionary <string, Distribution> GenerateNeighbour(Dictionary <string, Distribution> currentPar, double temp)
        {
            EPTDistribution      dist = (EPTDistribution)currentPar.First().Value;
            WIPDepDistParameters x    = dist.Par;

            WIPDepDistParameters par = new WIPDepDistParameters {
                WorkCenter = wc
            };

            UniformDistribution parDist = new UniformDistribution(0, Parameter.TotalWeight);
            double u = parDist.Next();

            // x is the original parameter set (input), par is a neighbouring parameter set
            // Change one parameter based on a probability
            if (isInRange("LBWIP", u))
            {
                par.LBWIP = (int)Math.Max(1, newValue("LBWIP", x.LBWIP));
            }
            else
            {
                par.LBWIP = x.LBWIP;
            }
            if (isInRange("UBWIP", u))
            {
                par.UBWIP = (int)Math.Max(1, newValue("UBWIP", x.UBWIP));
            }
            else
            {
                par.UBWIP = x.UBWIP;
            }
            if (isInRange("Tmin", u))
            {
                par.Tmin = newValue("Tmin", x.Tmin);
            }
            else
            {
                par.Tmin = x.Tmin;
            }
            if (isInRange("Tmax", u))
            {
                par.Tmax = newValue("Tmax", x.Tmax);
            }
            else
            {
                par.Tmax = x.Tmax;
            }
            if (isInRange("Tdecay", u))
            {
                par.Tdecay = newValue("Tdecay", x.Tdecay);
            }
            else
            {
                par.Tdecay = x.Tdecay;
            }
            if (isInRange("Cmin", u))
            {
                par.Cmin = newValue("Cmin", x.Cmin);
            }
            else
            {
                par.Cmin = x.Cmin;
            }
            if (isInRange("Cmax", u))
            {
                par.Cmax = newValue("Cmax", x.Cmax);
            }
            else
            {
                par.Cmax = x.Cmax;
            }
            if (isInRange("Cdecay", u))
            {
                par.Cdecay = newValue("Cdecay", x.Cdecay);
            }
            else
            {
                par.Cdecay = x.Cdecay;
            }

            Dictionary <string, Distribution> neighbour = new Dictionary <string, Distribution> {
                { wc, new EPTDistribution(par) }
            };

            return(neighbour);

            bool isInRange(string parName, double u)
            {
                Parameter parameter = ParConfig[parName];
                double    pLower    = parameter.CumulativeWeight - parameter.Weight;
                double    pUpper    = parameter.CumulativeWeight;

                if (u > pLower && u <= pUpper)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            double newValue(string parName, double value)
            {
                // Use Min-max feature scaling to determine the half width size of the new value
                // Large range at high temps (50%), small range at low temps (10%)
                double halfWidth = (0.5 - 0.1) * temp / maxTemp + 0.1;

                Parameter parameter = ParConfig[parName];

                double lowerBound = Math.Max(parameter.LowerBound, value - value * halfWidth);
                double upperBound = Math.Min(parameter.UpperBound, value + value * halfWidth);

                UniformDistribution valueDist = new UniformDistribution(lowerBound, upperBound);

                return(valueDist.Next());
            }
        }