Esempio n. 1
0
        public void AddResult(Dictionary <WIPDepDistParameters, Tuple <double, double> > results, Dictionary <string, Distribution> parameters, Tuple <double, double> result)
        {
            EPTDistribution      dist = (EPTDistribution)parameters.First().Value;
            WIPDepDistParameters x    = dist.Par;

            results.Add(x, result);
        }
Esempio n. 2
0
        // Mean and variance set in base are wrong and should not be used. This distribution does not have a single mean and variance, since it is WIP-dependent
        public EPTDistribution(WIPDepDistParameters parameters) : base(parameters.Tmax, parameters.Cmax)
        {
            Par = parameters;

            Distributions = new Dictionary <int, Distribution>();

            for (int WIP = 1; WIP <= Par.UBWIP; WIP++)
            {
                Distributions.Add(WIP, new GammaDistribution(MeanAtWIP(WIP), VarianceAtWIP(WIP)));
                //Console.WriteLine($"WIP: {WIP}, {MeanAtWIP(WIP)} \t {Math.Sqrt(VarianceAtWIP(WIP)/ (MeanAtWIP(WIP) * MeanAtWIP(WIP)))}");
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Write all evaluated paramater configurations to file
        /// </summary>
        public void WriteAllSolutions(Dictionary <WIPDepDistParameters, Tuple <double, double> > solutions, string wc)
        {
            using (StreamWriter writer = new StreamWriter(Path.Combine(outputDirectory, $"{wc}_parameters.txt")))
            {
                writer.WriteLine("LBWIP,UBWIP,Tmin,Tmax,Tdecay,Cmin,Cmax,Cdecay,AverageQL,StdQL");

                foreach (KeyValuePair <WIPDepDistParameters, Tuple <double, double> > solution in solutions)
                {
                    WIPDepDistParameters   pars   = solution.Key;
                    Tuple <double, double> result = solution.Value;
                    writer.WriteLine(pars.LBWIP + "," + pars.UBWIP + "," + pars.Tmin + "," + pars.Tmax + "," + pars.Tdecay + "," + pars.Cmin + "," + pars.Cmax + "," + pars.Cdecay
                                     + "," + result.Item1 + "," + result.Item2);
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Write current and best parameter configurations to file.
        /// </summary>
        public void WriteFinalSolutions(Dictionary <string, Distribution> currentPar, Tuple <double, double> currentRes,
                                        Dictionary <string, Distribution> bestPar, Tuple <double, double> bestRes, string wc)
        {
            using (StreamWriter writer = new StreamWriter(Path.Combine(outputDirectory, $"{wc}_best_parameters.txt")))
            {
                writer.WriteLine("Parameters,LBWIP,UBWIP,Tmin,Tmax,Tdecay,Cmin,Cmax,Cdecay,AverageQL,StdQL");

                EPTDistribution      dist = (EPTDistribution)currentPar.First().Value;
                WIPDepDistParameters par  = dist.Par;


                writer.WriteLine($"Current,{par.LBWIP},{par.UBWIP},{par.Tmin},{par.Tmax},{par.Tdecay},{par.Cmin},{par.Cmax},{par.Cdecay},{currentRes.Item1},{currentRes.Item2}");

                dist = (EPTDistribution)bestPar.First().Value;
                par  = dist.Par;

                writer.WriteLine($"Best,{par.LBWIP},{par.UBWIP},{par.Tmin},{par.Tmax},{par.Tdecay},{par.Cmin},{par.Cmax},{par.Cdecay},{bestRes.Item1},{bestRes.Item2}");
            }
        }
Esempio n. 5
0
        public Dictionary <string, Distribution> CopyParameters(Dictionary <string, Distribution> parameters)
        {
            EPTDistribution      dist = (EPTDistribution)parameters.First().Value;
            WIPDepDistParameters x    = dist.Par;

            WIPDepDistParameters pars = new WIPDepDistParameters
            {
                LBWIP  = x.LBWIP,
                UBWIP  = x.UBWIP,
                Tmin   = x.Tmin,
                Tmax   = x.Tmax,
                Tdecay = x.Tdecay,
                Cmin   = x.Cmin,
                Cmax   = x.Cmax,
                Cdecay = x.Cdecay
            };

            Dictionary <string, Distribution> copiedParameters = new Dictionary <string, Distribution>
            {
                { wc, new EPTDistribution(pars) }
            };

            return(copiedParameters);
        }
Esempio n. 6
0
        public Dictionary <string, Distribution> GetServiceTimeDistributions(string eptParameterFile)
        {
            Dictionary <string, Distribution> dict = new Dictionary <string, Distribution>();

            Dictionary <string, WIPDepDistParameters> parameters = new Dictionary <string, WIPDepDistParameters>();

            // Read fitted WIP dependent EPT parameters from csv
            using (StreamReader reader = new StreamReader(Path.Combine(directory, eptParameterFile)))
            {
                string[] headers = reader.ReadLine().Trim(',').Split(',');

                while (!reader.EndOfStream)
                {
                    WIPDepDistParameters par = new WIPDepDistParameters();

                    string[] data = reader.ReadLine().Trim(',').Split(',');

                    for (int i = 0; i < data.Length; i++)
                    {
                        if (headers[i] == "WorkStation")
                        {
                            if (!workcenters.Contains(data[i]))
                            {
                                throw new Exception($"Waferfab does not contain workcenter {data[i]}");
                            }
                            par.WorkCenter = data[i];
                        }
                        if (headers[i] == "wip_min")
                        {
                            par.LBWIP = (int)double.Parse(data[i]);
                        }
                        if (headers[i] == "wip_max")
                        {
                            par.UBWIP = (int)double.Parse(data[i]);
                        }
                        if (headers[i] == "t_min")
                        {
                            par.Tmin = double.Parse(data[i]);
                        }
                        if (headers[i] == "t_max")
                        {
                            par.Tmax = double.Parse(data[i]);
                        }
                        if (headers[i] == "t_decay")
                        {
                            par.Tdecay = double.Parse(data[i]);
                        }
                        if (headers[i] == "c_min")
                        {
                            par.Cmin = double.Parse(data[i]);
                        }
                        if (headers[i] == "c_max")
                        {
                            par.Cmax = double.Parse(data[i]);
                        }
                        if (headers[i] == "c_decay")
                        {
                            par.Cdecay = double.Parse(data[i]);
                        }
                    }

                    parameters.Add(par.WorkCenter, par);
                }
            }

            foreach (string wc in workcenters)
            {
                dict.Add(wc, new EPTDistribution(parameters[wc]));
            }

            return(dict);
        }
Esempio n. 7
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());
            }
        }
Esempio n. 8
0
        public EPTDistribution CheckInitialDistBounds(EPTDistribution dist)
        {
            WIPDepDistParameters x = dist.Par;

            // For each initial value, check if it is within bounds. If not, set to closest bound
            if (x.Tmin < ParConfig["Tmin"].LowerBound)
            {
                x.Tmin = ParConfig["Tmin"].LowerBound;
            }
            else if (x.Tmin > ParConfig["Tmin"].UpperBound)
            {
                x.Tmin = ParConfig["Tmin"].UpperBound;
            }

            if (x.Tmax < ParConfig["Tmax"].LowerBound)
            {
                x.Tmax = ParConfig["Tmax"].LowerBound;
            }
            else if (x.Tmax > ParConfig["Tmax"].UpperBound)
            {
                x.Tmax = ParConfig["Tmax"].UpperBound;
            }

            if (x.Tdecay < ParConfig["Tdecay"].LowerBound)
            {
                x.Tdecay = ParConfig["Tdecay"].LowerBound;
            }
            else if (x.Tdecay > ParConfig["Tdecay"].UpperBound)
            {
                x.Tdecay = ParConfig["Tdecay"].UpperBound;
            }


            if (x.Cmin < ParConfig["Cmin"].LowerBound)
            {
                x.Cmin = ParConfig["Cmin"].LowerBound;
            }
            else if (x.Cmin > ParConfig["Cmin"].UpperBound)
            {
                x.Cmin = ParConfig["Cmin"].UpperBound;
            }

            if (x.Cmax < ParConfig["Cmax"].LowerBound)
            {
                x.Cmax = ParConfig["Cmax"].LowerBound;
            }
            else if (x.Cmax > ParConfig["Cmax"].UpperBound)
            {
                x.Cmax = ParConfig["Cmax"].UpperBound;
            }

            if (x.Cdecay < ParConfig["Cdecay"].LowerBound)
            {
                x.Cdecay = ParConfig["Cdecay"].LowerBound;
            }
            else if (x.Cdecay > ParConfig["Cdecay"].UpperBound)
            {
                x.Cdecay = ParConfig["Cdecay"].UpperBound;
            }

            EPTDistribution newDist = new EPTDistribution(x);

            return(newDist);
        }
Esempio n. 9
0
        public Tuple <double, double> RunSim(Dictionary <string, Distribution> dict)
        {
            EPTDistribution      dist = (EPTDistribution)dict.First().Value;
            WIPDepDistParameters x    = dist.Par;

            waferFabSettings.WCServiceTimeDistributions = new Dictionary <string, Distribution> {
                { wc, new EPTDistribution(x) }
            };

            #region Initializing simulation
            Simulation simulation = new Simulation("CSSLWaferFabArea", outputDirectory);
            #endregion

            #region Experiment settings
            simulation.MyExperiment.NumberOfReplications = 10;

            DateTime finalDateTime = new DateTime(2019, initialDateTime.Month + 2, 1);
            simulation.MyExperiment.LengthOfReplication = (finalDateTime - initialDateTime).TotalSeconds; // Number of seconds between two months

            simulation.MyExperiment.LengthOfWarmUp = 60 * 60 * 24 * 0;
            #endregion

            #region Building the model
            WaferFab waferFab = new WaferFab(simulation.MyModel, "WaferFab", new ConstantDistribution(60 * 60 * 24), initialDateTime);

            WorkCenter workCenter = new WorkCenter(waferFab, $"WorkCenter_{wc}", waferFabSettings.WCServiceTimeDistributions[wc], waferFabSettings.LotStepsPerWorkStation[wc]);

            // Connect workcenter to WIPDependentDistribution
            EPTDistribution distr = (EPTDistribution)waferFabSettings.WCServiceTimeDistributions[wc];

            distr.WorkCenter = workCenter;

            EPTOvertakingDispatcher dispatcher = new EPTOvertakingDispatcher(workCenter, workCenter.Name + "_EPTOvertakingDispatcher", waferFabSettings.WCOvertakingDistributions[wc]);
            workCenter.SetDispatcher(dispatcher);

            // Connect workcenter to OvertakingDistribution
            waferFabSettings.WCOvertakingDistributions[wc].WorkCenter = workCenter;

            waferFab.AddWorkCenter(workCenter.Name, workCenter);

            // Sequences
            foreach (var sequence in waferFabSettings.Sequences)
            {
                waferFab.AddSequence(sequence.Key, sequence.Value);
            }

            // LotSteps
            waferFab.LotSteps = waferFab.Sequences.Select(x => x.Value).Select(x => x.GetCurrentStep(0)).ToDictionary(x => x.Name);

            // LotGenerator
            waferFab.SetLotGenerator(new LotGenerator(waferFab, "LotGenerator", new ConstantDistribution(60), true));

            // Add lotstarts
            waferFab.LotStarts = waferFabSettings.LotStarts;

            // Add initial lots
            if (useInitialLots)
            {
                List <Lot> initialLotsDeepCopy = initialLots.ConvertAll(x => new Lot(x));
                waferFab.InitialLots = initialLotsDeepCopy;
            }

            // Add observers
            OptimiserObserver optimiserObs = new OptimiserObserver(simulation, wc + "_TotalQueueObserver");
            workCenter.Subscribe(optimiserObs); // Total queue for workcenter
            #endregion

            simulation.Run();

            #region Reporting
            SimulationReporter reporter = simulation.MakeSimulationReporter();

            reporter.PrintSummaryToConsole();
            #endregion

            Tuple <double, double> results = new Tuple <double, double>(optimiserObs.QueueLengthStatistic.Average(), optimiserObs.QueueLengthStatistic.StandardDeviation());

            return(results);
        }