예제 #1
0
        public WaferAreaSim(string wc, string eptParameterFile, string inputDirectory, string outputDirectory, DateTime initialDateTime, Optimiser optimiser, bool useInitialLots = false)
        {
            this.wc = wc;

            this.inputDirectory = inputDirectory;

            this.outputDirectory = outputDirectory;

            this.initialDateTime = initialDateTime;

            this.optimiser = optimiser;

            this.useInitialLots = useInitialLots;

            #region WaferFab settings
            waferFabSettings = Deserializer.DeserializeWaferFabSettings(Path.Combine(inputDirectory, "SerializedFiles", $"WaferFabSettings_{wc}_WithLotStarts.dat"));

            distributionReader = new EPTDistributionReader(Path.Combine(inputDirectory, "CSVs"), waferFabSettings.WorkCenters, waferFabSettings.LotStepsPerWorkStation);

            // Get initial parameters
            waferFabSettings.WCServiceTimeDistributions = distributionReader.GetServiceTimeDistributions(eptParameterFile);

            EPTDistribution initialDist = (EPTDistribution)waferFabSettings.WCServiceTimeDistributions[wc];
            InitialParameters = new Dictionary <string, Distribution> {
                { wc, optimiser.CheckInitialDistBounds(initialDist) }
            };

            waferFabSettings.WCOvertakingDistributions = distributionReader.GetOvertakingDistributions();
            #endregion

            if (useInitialLots)
            {
                initialLots = optimiser.GetInitialLots(wc, inputDirectory, outputDirectory, initialDateTime, waferFabSettings);
            }
        }
예제 #2
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
            }
        }