/// <summary>
        /// This runs the iterations for the ES
        /// </summary>
        /// <param name="p_pb">Used for accessing progress bar in main form</param>
        /// <param name="p_tb">Used for accessing textbox in main form</param>
        /// <param name="p_form1">Used for accesing main form objects</param>
        /// <param name="p_wh">Warehouse object used for accesing main form warehouse object</param>
        /// <param name="p_problemfolder">Problemfolder is null when batch optimization is not used, otherwise it uses the location of the folder for batch optimization</param>
        public void Solve(System.Windows.Forms.ProgressBar p_pb, System.Windows.Forms.TextBox p_tb, MainForm p_form1, warehouse p_wh, string p_problemfolder)
        {
            string searchtype = "";

            if (allsearch)
            {
                searchtype = "AllSearch";
            }
            else
            {
                searchtype = "DynamicSearch";
            }
            string experimentdirectoryorg = p_problemfolder + "\\ES-" + M.ToString() + "-" + lambda.ToString() + "-" + seed.ToString() + "-" + iteration.ToString() + "-" + sigma.ToString().Replace(".", string.Empty) + "-" + counter.ToString() + "-" + searchtype;
            int    k = 0;
            string experimentdirectory = experimentdirectoryorg;

            while (System.IO.Directory.Exists(experimentdirectory))
            {
                if (k != 0)//in first folder creation don't put index to the end
                {
                    experimentdirectory = experimentdirectoryorg + "-" + k.ToString();
                }
                k++;
            }

            System.IO.Directory.CreateDirectory(experimentdirectory);

            p_pb.Style   = System.Windows.Forms.ProgressBarStyle.Continuous;
            p_pb.Maximum = 100;
            p_pb.Value   = 0;
            double    previouscost = double.MaxValue;
            csvexport myexcel      = new csvexport();

            //Save initial population as first row in excel file
            myexcel.addRow();
            myexcel["Cost"]          = getCost().ToString("R");
            myexcel["Locs"]          = getBestWarehouse().totalNumberOfLocations().ToString();
            myexcel["SR"]            = "None";
            myexcel["Width"]         = getBestWarehouse().getWidth().ToString("R");
            myexcel["Depth"]         = getBestWarehouse().getDepth().ToString("R");
            myexcel["Area"]          = getBestWarehouse().area.ToString("R");
            myexcel["Ratio"]         = getBest().getx()[0].ToString("R");
            myexcel["E1"]            = getBest().getx()[1].ToString("R");
            myexcel["E2"]            = getBest().getx()[2].ToString("R");
            myexcel["E3"]            = getBest().getx()[3].ToString("R");
            myexcel["E4"]            = getBest().getx()[4].ToString("R");
            myexcel["I1X"]           = getBest().getx()[5].ToString("R");
            myexcel["I1Y"]           = getBest().getx()[6].ToString("R");
            myexcel["PD"]            = getBest().getx()[7].ToString("R");
            myexcel["Angle1"]        = (180 * getBest().getx()[8]).ToString("R");
            myexcel["Angle2"]        = (180 * getBest().getx()[9]).ToString("R");
            myexcel["Angle3"]        = (180 * getBest().getx()[10]).ToString("R");
            myexcel["Angle4"]        = (180 * getBest().getx()[11]).ToString("R");
            myexcel["Angle5"]        = (180 * getBest().getx()[12]).ToString("R");
            myexcel["Angle6"]        = (180 * getBest().getx()[13]).ToString("R");
            myexcel["Angle7"]        = (180 * getBest().getx()[14]).ToString("R");
            myexcel["Angle8"]        = (180 * getBest().getx()[15]).ToString("R");
            myexcel["Adjuster1"]     = getBest().getx()[16].ToString("R");
            myexcel["Adjuster2"]     = getBest().getx()[17].ToString("R");
            myexcel["Adjuster3"]     = getBest().getx()[18].ToString("R");
            myexcel["Adjuster4"]     = getBest().getx()[19].ToString("R");
            myexcel["Adjuster5"]     = getBest().getx()[20].ToString("R");
            myexcel["Adjuster6"]     = getBest().getx()[21].ToString("R");
            myexcel["Adjuster7"]     = getBest().getx()[22].ToString("R");
            myexcel["Adjuster8"]     = getBest().getx()[23].ToString("R");
            myexcel["PickAdjuster1"] = getBest().getx()[24].ToString("R");
            myexcel["PickAdjuster2"] = getBest().getx()[25].ToString("R");
            myexcel["PickAdjuster3"] = getBest().getx()[26].ToString("R");
            myexcel["PickAdjuster4"] = getBest().getx()[27].ToString("R");
            myexcel["PickAdjuster5"] = getBest().getx()[28].ToString("R");
            myexcel["PickAdjuster6"] = getBest().getx()[29].ToString("R");
            myexcel["PickAdjuster7"] = getBest().getx()[30].ToString("R");
            myexcel["PickAdjuster8"] = getBest().getx()[31].ToString("R");
            myexcel["PC12"]          = getBest().getx()[32].ToString("R");
            myexcel["PC13"]          = getBest().getx()[33].ToString("R");
            myexcel["PC14"]          = getBest().getx()[34].ToString("R");
            myexcel["PC15"]          = getBest().getx()[35].ToString("R");
            myexcel["PC23"]          = getBest().getx()[36].ToString("R");
            myexcel["PC24"]          = getBest().getx()[37].ToString("R");
            myexcel["PC25"]          = getBest().getx()[38].ToString("R");
            myexcel["PC34"]          = getBest().getx()[39].ToString("R");
            myexcel["PC35"]          = getBest().getx()[40].ToString("R");
            myexcel["PC45"]          = getBest().getx()[41].ToString("R");
            myexcel["C12"]           = getBest().getx()[42].ToString();
            myexcel["C13"]           = getBest().getx()[43].ToString();
            myexcel["C14"]           = getBest().getx()[44].ToString();
            myexcel["C15"]           = getBest().getx()[45].ToString();
            myexcel["C23"]           = getBest().getx()[46].ToString();
            myexcel["C24"]           = getBest().getx()[47].ToString();
            myexcel["C25"]           = getBest().getx()[48].ToString();
            myexcel["C34"]           = getBest().getx()[49].ToString();
            myexcel["C35"]           = getBest().getx()[50].ToString();
            myexcel["C45"]           = getBest().getx()[51].ToString();
            myexcel.exportToFile(experimentdirectory + "\\experiment.csv");
            //Print the first layout
            previouscost = getCost();
            p_wh.resetNetwork();
            //Reset IDs
            edge.nextID   = 0;
            region.nextID = 0;
            node.nextID   = 0;
            double[] angle        = { 180 * getBest().getx()[8], 180 * getBest().getx()[9], 180 * getBest().getx()[10], 180 * getBest().getx()[11], 180 * getBest().getx()[12], 180 * getBest().getx()[13], 180 * getBest().getx()[14], 180 * getBest().getx()[15] };
            double[] adjuster     = { getBest().getx()[16], getBest().getx()[17], getBest().getx()[18], getBest().getx()[19], getBest().getx()[20], getBest().getx()[21], getBest().getx()[22], getBest().getx()[23] };
            double[] pickadjuster = { getBest().getx()[24], getBest().getx()[25], getBest().getx()[26], getBest().getx()[27], getBest().getx()[28], getBest().getx()[29], getBest().getx()[30], getBest().getx()[31] };
            double[] ext          = { getBest().getx()[1], getBest().getx()[2], getBest().getx()[3], getBest().getx()[4] };
            double[] intx         = { getBest().getx()[5] };
            double[] inty         = { getBest().getx()[6] };
            double[] pd           = { getBest().getx()[7] };
            double   aspectratio  = getBest().getx()[0];

            p_wh.aspectratio = aspectratio;
            p_wh.setArea(getBestWarehouse().area);

            bool[] connections = new bool[this.size - l.Count()];
            int    c           = 0;

            for (int j = l.Count(); j < this.size; j++)
            {
                int indexencodingprobability = j - (this.size - l.Count());
                if (getBest().getx()[j] == 0)//If that cross aisle exists then select that connection correct
                {
                    connections[c] = false;
                }
                else
                {
                    connections[c] = true;
                }
                c++;
            }

            if (!p_wh.createWarehouse(angle, adjuster, pickadjuster, ext, intx, inty, pd, aspectratio, p_wh.crossaislewidth, p_wh.pickingaislewidth, p_wh.pickinglocationwidth, p_wh.pickinglocationdepth, connections))
            {
                return;
            }

            if (!p_wh.usevisibilitygraph)//Aisle centers method
            {
                p_wh.createImportantNodeShortestDistances();
                p_wh.locationShortestDistance();//Calculate Shortest Path Distances for Locations
            }
            else//Visibility graph method
            {
                p_wh.createPolygonsandGraphNodes();
                p_wh.createVisibilityGraph();
                p_wh.fillGraphNodeDistances();
            }
            //Calculate Shortest Path Distances to PD
            p_wh.pdTotalDistances();
            p_wh.totalDistances();
            p_wh.rankLocations(Convert.ToDouble(p_wh.avgTourLength));
            p_wh.colorOverall();

            p_form1.drawCompleteWarehouse(p_wh.getWidth(), p_wh.getDepth());
            p_form1.saveBitmap(experimentdirectory + "\\0.bmp");
            //End print the first layout
            int counter1 = 0;
            int counter2 = 1;

            generalsuccess = 0;
            generalfail    = 0;
            //This costarray is used to check for the last 100 iterations if there is improvement less than %0.5 then makes it early quit the for loop
            double[] costarray = new double[iteration];
            for (int i = 0; i < iteration; i++)
            {
                if (counter1 == this.counter)
                {
                    counter2++;
                    //Increase the step size if success rate is greater than 0.2 (or whatever is successrule) and decrease the step size otherwise
                    if ((double)numberofsuccessfulchildrencreated / (double)numberofchildrencreated > successrule)
                    {
                        sigma = sigma / 0.85;
                        generalsuccess++;
                    }
                    else
                    {
                        sigma = sigma * 0.85;
                        generalfail++;
                    }
                    counter1 = 0;
                    numberofsuccessfulchildrencreated = 0;
                    numberofchildrencreated           = 0;
                    if (allsearch)
                    {
                        numberoforders = wh.getOrders().Count();
                    }
                    else
                    {
                        numberoforders = Convert.ToInt32(Convert.ToDouble(counter2) / Convert.ToDouble(numberofgaps) * wh.getOrders().Count());
                    }
                }
                counter1++;
                DateTime start   = DateTime.Now;
                string   logfile = experimentdirectory + "\\log.csv";
                evolution(i, logfile);
                double successrateperiteration = Convert.ToDouble(numberofsuccessfulchildrencreatedperiteration) / Convert.ToDouble(lambda);
                numberofsuccessfulchildrencreatedperiteration = 0;//Resetsucessperiteration
                TimeSpan elapsed = DateTime.Now - start;
                p_pb.Value = Convert.ToInt32(Convert.ToDouble(i + 1) / Convert.ToDouble(iteration) * 100);
                p_tb.AppendText("Iteration" + (i + 1).ToString() + ": " + getCost().ToString("0.000") + " Time: " + elapsed.ToString() + " SR:" + successrateperiteration.ToString("0.000") + "\n");
                double currentcost = double.MaxValue;
                if (!usenft)
                {
                    currentcost = getCost();
                }
                else
                {
                    currentcost = getCost(i, nft0, nftlambda);
                }
                myexcel = new csvexport();
                myexcel.addRow();
                costarray[i]             = currentcost;
                myexcel["Cost"]          = getCost().ToString("R");
                myexcel["Locs"]          = getBestWarehouse().totalNumberOfLocations().ToString();
                myexcel["SR"]            = successrateperiteration.ToString("R");
                myexcel["Width"]         = getBestWarehouse().getWidth().ToString("R");
                myexcel["Depth"]         = getBestWarehouse().getDepth().ToString("R");
                myexcel["Area"]          = getBestWarehouse().area.ToString("R");
                myexcel["Ratio"]         = getBest().getx()[0].ToString("R");
                myexcel["E1"]            = getBest().getx()[1].ToString("R");
                myexcel["E2"]            = getBest().getx()[2].ToString("R");
                myexcel["E3"]            = getBest().getx()[3].ToString("R");
                myexcel["E4"]            = getBest().getx()[4].ToString("R");
                myexcel["I1X"]           = getBest().getx()[5].ToString("R");
                myexcel["I1Y"]           = getBest().getx()[6].ToString("R");
                myexcel["PD"]            = getBest().getx()[7].ToString("R");
                myexcel["Angle1"]        = (180 * getBest().getx()[8]).ToString("R");
                myexcel["Angle2"]        = (180 * getBest().getx()[9]).ToString("R");
                myexcel["Angle3"]        = (180 * getBest().getx()[10]).ToString("R");
                myexcel["Angle4"]        = (180 * getBest().getx()[11]).ToString("R");
                myexcel["Angle5"]        = (180 * getBest().getx()[12]).ToString("R");
                myexcel["Angle6"]        = (180 * getBest().getx()[13]).ToString("R");
                myexcel["Angle7"]        = (180 * getBest().getx()[14]).ToString("R");
                myexcel["Angle8"]        = (180 * getBest().getx()[15]).ToString("R");
                myexcel["Adjuster1"]     = getBest().getx()[16].ToString("R");
                myexcel["Adjuster2"]     = getBest().getx()[17].ToString("R");
                myexcel["Adjuster3"]     = getBest().getx()[18].ToString("R");
                myexcel["Adjuster4"]     = getBest().getx()[19].ToString("R");
                myexcel["Adjuster5"]     = getBest().getx()[20].ToString("R");
                myexcel["Adjuster6"]     = getBest().getx()[21].ToString("R");
                myexcel["Adjuster7"]     = getBest().getx()[22].ToString("R");
                myexcel["Adjuster8"]     = getBest().getx()[23].ToString("R");
                myexcel["PickAdjuster1"] = getBest().getx()[24].ToString("R");
                myexcel["PickAdjuster2"] = getBest().getx()[25].ToString("R");
                myexcel["PickAdjuster3"] = getBest().getx()[26].ToString("R");
                myexcel["PickAdjuster4"] = getBest().getx()[27].ToString("R");
                myexcel["PickAdjuster5"] = getBest().getx()[28].ToString("R");
                myexcel["PickAdjuster6"] = getBest().getx()[29].ToString("R");
                myexcel["PickAdjuster7"] = getBest().getx()[30].ToString("R");
                myexcel["PickAdjuster8"] = getBest().getx()[31].ToString("R");
                myexcel["PC12"]          = getBest().getx()[32].ToString("R");
                myexcel["PC13"]          = getBest().getx()[33].ToString("R");
                myexcel["PC14"]          = getBest().getx()[34].ToString("R");
                myexcel["PC15"]          = getBest().getx()[35].ToString("R");
                myexcel["PC23"]          = getBest().getx()[36].ToString("R");
                myexcel["PC24"]          = getBest().getx()[37].ToString("R");
                myexcel["PC25"]          = getBest().getx()[38].ToString("R");
                myexcel["PC34"]          = getBest().getx()[39].ToString("R");
                myexcel["PC35"]          = getBest().getx()[40].ToString("R");
                myexcel["PC45"]          = getBest().getx()[41].ToString("R");
                myexcel["C12"]           = getBest().getx()[42].ToString();
                myexcel["C13"]           = getBest().getx()[43].ToString();
                myexcel["C14"]           = getBest().getx()[44].ToString();
                myexcel["C15"]           = getBest().getx()[45].ToString();
                myexcel["C23"]           = getBest().getx()[46].ToString();
                myexcel["C24"]           = getBest().getx()[47].ToString();
                myexcel["C25"]           = getBest().getx()[48].ToString();
                myexcel["C34"]           = getBest().getx()[49].ToString();
                myexcel["C35"]           = getBest().getx()[50].ToString();
                myexcel["C45"]           = getBest().getx()[51].ToString();
                myexcel.appendToFile(experimentdirectory + "\\experiment.csv");

                //There is a new best warehouse so print the layout to the screen
                if (currentcost < previouscost)
                {
                    previouscost = currentcost;
                    p_wh.resetNetwork();
                    //Reset IDs
                    edge.nextID   = 0;
                    region.nextID = 0;
                    node.nextID   = 0;
                    double[] angle1        = { 180 * getBest().getx()[8], 180 * getBest().getx()[9], 180 * getBest().getx()[10], 180 * getBest().getx()[11], 180 * getBest().getx()[12], 180 * getBest().getx()[13], 180 * getBest().getx()[14], 180 * getBest().getx()[15] };
                    double[] adjuster1     = { getBest().getx()[16], getBest().getx()[17], getBest().getx()[18], getBest().getx()[19], getBest().getx()[20], getBest().getx()[21], getBest().getx()[22], getBest().getx()[23] };
                    double[] pickadjuster1 = { getBest().getx()[24], getBest().getx()[25], getBest().getx()[26], getBest().getx()[27], getBest().getx()[28], getBest().getx()[29], getBest().getx()[30], getBest().getx()[31] };
                    double[] ext1          = { getBest().getx()[1], getBest().getx()[2], getBest().getx()[3], getBest().getx()[4] };
                    double[] intx1         = { getBest().getx()[5] };
                    double[] inty1         = { getBest().getx()[6] };
                    double[] pd1           = { getBest().getx()[7] };
                    double   aspectratio1  = getBest().getx()[0];
                    p_wh.aspectratio = aspectratio1;
                    p_wh.setArea(getBestWarehouse().area);

                    bool[] connections1 = new bool[this.size - l.Count()];
                    int    m            = 0;
                    for (int j = l.Count(); j < this.size; j++)
                    {
                        int indexencodingprobability = j - (this.size - l.Count());
                        if (getBest().getx()[j] == 0)//If that cross aisle exists then select that connection correct
                        {
                            connections1[m] = false;
                        }
                        else
                        {
                            connections1[m] = true;
                        }
                        m++;
                    }

                    if (!p_wh.createWarehouse(angle1, adjuster1, pickadjuster1, ext1, intx1, inty1, pd1, aspectratio1, p_wh.crossaislewidth, p_wh.pickingaislewidth, p_wh.pickinglocationwidth, p_wh.pickinglocationdepth, connections1))
                    {
                        return;
                    }

                    if (!p_wh.usevisibilitygraph)//Aisle centers method
                    {
                        p_wh.createImportantNodeShortestDistances();
                        //Calculate Shortest Path Distances for Locations
                        p_wh.locationShortestDistance();
                    }
                    else//Visibility graph method
                    {
                        p_wh.createPolygonsandGraphNodes();
                        p_wh.createVisibilityGraph();
                        p_wh.fillGraphNodeDistances();
                    }
                    //Calculate Shortest Path Distances to PD
                    p_wh.pdTotalDistances();
                    p_wh.totalDistances();
                    p_wh.rankLocations(Convert.ToDouble(p_wh.avgTourLength));
                    p_wh.colorOverall();

                    p_form1.drawCompleteWarehouse(p_wh.getWidth(), p_wh.getDepth());
                    p_form1.saveBitmap(experimentdirectory + "\\" + (i + 1).ToString() + ".bmp");
                }//end of printing if there is an improvement
                //Perform early termination if there is no significant (more than 0.5 percent) improvement for the last 100 iterations
                if (i >= 100 && ((costarray[i - 100] - costarray[i]) / costarray[i - 100]) < 0.005)
                {
                    break;
                }
            }//end of iteration
        }
Exemple #2
0
        private bool infeasibledesign; //true if the design/solution is infeasible

        /// <summary>
        /// Constructor for a solution it automatically calculates the feasibility of the solution
        /// If it is feasible, it calculates the cost, if it is infeasible it sets the infeasibledesign variable to true
        /// </summary>
        /// <param name="p_numberofparameters">Total number of parameters for a solution</param>
        /// <param name="p_x">Solution array</param>
        /// <param name="p_l">Lower bound array</param>
        /// <param name="p_u">Upper bound array</param>
        /// <param name="p_wh">Warehouse object that is used for compututation for solution variables</param>
        /// <param name="p_o">Number of orders being calculated, this number can be lower than total number of orders (this is used for sampling)</param>
        /// <param name="p_computing">0 is Parallel, 1 is Distributed, 2 is Single Thread Computing</param>
        /// <param name="p_optimal">True use Concorde, False use LKH</param>
        /// <param name="p_socketservers">List of servers for distributed computing</param>
        /// <param name="p_designclass">Search All design classes or a specific design class</param>
        public esvariable(int p_numberofparameters, double[] p_x, double[] p_l, double[] p_u, warehouse p_wh, int p_o, int p_computing, bool p_optimal, socketservers p_socketservers, string p_designclass)
        {
            numberofparameters = p_numberofparameters;
            designclass        = p_designclass;
            x = new double[numberofparameters];
            u = new double[p_u.Count()];
            l = new double[p_l.Count()];
            u = p_u;
            l = p_l;
            bool warehousefit = false;
            bool finalize     = false;

            infeasibledesign = false;
            setx(p_x);
            wh             = new warehouse();
            wh.aspectratio = x[0];
            wh.setArea(p_wh.area);
            wh.usevisibilitygraph = p_wh.usevisibilitygraph;
            wh.pickersize         = p_wh.pickersize;

            //Adjust warehouse area until warehouse is fit (minimum number of empty locations with given aspect ratio)
            int increased = 0;
            int decreased = 0;

            do
            {
                wh.resetNetwork();
                //Set warehouse aspect ratio
                wh.aspectratio = x[0];
                //Set warehouse cross aisle width
                wh.crossaislewidth = p_wh.crossaislewidth;
                //Set warehouse picking aisle width
                wh.pickingaislewidth = p_wh.pickingaislewidth;
                //Set warehouse picking location width
                wh.pickinglocationwidth = p_wh.pickinglocationwidth;
                //Set warehouse picking location depth
                wh.pickinglocationdepth = p_wh.pickinglocationdepth;
                //Set SKUs for the warehouse object
                wh.setSKUs(p_wh.getSKUs());
                //Set average number of picks per pick tour
                wh.avgTourLength = p_wh.avgTourLength;

                if (designclass != "All")//Perform search on a specific design class
                {
                    double[] angle        = { 180 * x[8], 180 * x[9], 180 * x[10], 180 * x[11], 180 * x[12], 180 * x[13] };
                    double[] adjuster     = { x[14], x[15], x[16], x[17], x[18], x[19] };
                    double[] pickadjuster = { x[20], x[21], x[22], x[23], x[24], x[25] };
                    double[] ext          = { x[1], x[2], x[3], x[4], x[5], x[6] };
                    double[] intx         = { x[5] };
                    double[] inty         = { x[6] };
                    double[] pd           = { x[7] };
                    double   aspectratio  = x[0];

                    switch (designclass)
                    {
                    case "0-0-0":
                        if (!wh.create000Warehouse(angle, adjuster, pickadjuster, ext, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth))
                        {
                            cost             = Double.MaxValue;//This means infeasible design
                            infeasibledesign = true;
                            return;
                        }
                        break;

                    case "2-0-1":
                        if (!wh.create201Warehouse(angle, adjuster, pickadjuster, ext, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth))
                        {
                            cost             = Double.MaxValue;
                            infeasibledesign = true;
                            return;
                        }
                        break;

                    case "3-0-2":
                        if (!wh.create302Warehouse(angle, adjuster, pickadjuster, ext, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth))
                        {
                            cost             = Double.MaxValue;
                            infeasibledesign = true;
                            return;
                        }
                        break;

                    case "3-0-3":
                        if (!wh.create303Warehouse(angle, adjuster, pickadjuster, ext, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth))
                        {
                            cost             = Double.MaxValue;
                            infeasibledesign = true;
                            return;
                        }
                        break;

                    case "3-1-3":
                        if (!wh.create313Warehouse(angle, adjuster, pickadjuster, ext, intx, inty, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth))
                        {
                            cost             = Double.MaxValue;
                            infeasibledesign = true;
                            return;
                        }
                        break;

                    case "4-0-2":
                        if (!wh.create402Warehouse(angle, adjuster, pickadjuster, ext, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth))
                        {
                            cost             = Double.MaxValue;
                            infeasibledesign = true;
                            return;
                        }
                        break;

                    case "4-0-4":
                        if (!wh.create404Warehouse(angle, adjuster, pickadjuster, ext, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth))
                        {
                            cost             = Double.MaxValue;
                            infeasibledesign = true;
                            return;
                        }
                        break;

                    case "4-0-5":
                        if (!wh.create405Warehouse(angle, adjuster, pickadjuster, ext, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth))
                        {
                            cost             = Double.MaxValue;
                            infeasibledesign = true;
                            return;
                        }
                        break;

                    case "4-1-4":
                        if (!wh.create414Warehouse(angle, adjuster, pickadjuster, ext, intx, inty, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth))
                        {
                            cost             = Double.MaxValue;
                            infeasibledesign = true;
                            return;
                        }
                        break;

                    case "4-2-5":
                        if (!wh.create425Warehouse(angle, adjuster, pickadjuster, ext, intx, inty, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth))
                        {
                            cost             = Double.MaxValue;
                            infeasibledesign = true;
                            return;
                        }
                        break;

                    case "6-0-3":
                        if (!wh.create603Warehouse(angle, adjuster, pickadjuster, ext, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth))
                        {
                            cost             = Double.MaxValue;
                            infeasibledesign = true;
                            return;
                        }
                        break;
                    }
                }
                else//Perform search on all design classes
                {
                    double[] angle        = { 180 * x[8], 180 * x[9], 180 * x[10], 180 * x[11], 180 * x[12], 180 * x[13], 180 * x[14], 180 * x[15] };
                    double[] adjuster     = { x[16], x[17], x[18], x[19], x[20], x[21], x[22], x[23] };
                    double[] pickadjuster = { x[24], x[25], x[26], x[27], x[28], x[29], x[30], x[31] };
                    double[] ext          = { x[1], x[2], x[3], x[4] };
                    double[] intx         = { x[5] };
                    double[] inty         = { x[6] };
                    double[] pd           = { x[7] };
                    double   aspectratio  = x[0];

                    bool[] connections = new bool[this.numberofparameters - l.Count()];
                    int    m           = 0;
                    for (int j = l.Count(); j < this.numberofparameters; j++)
                    {
                        int indexencodingprobability = j - (this.numberofparameters - l.Count());
                        if (x[j] == 0)//If that cross aisle exists then select that connection correct
                        {
                            connections[m] = false;
                        }
                        else
                        {
                            connections[m] = true;
                        }
                        m++;
                    }

                    if (!wh.createWarehouse(angle, adjuster, pickadjuster, ext, intx, inty, pd, aspectratio, wh.crossaislewidth, wh.pickingaislewidth, wh.pickinglocationwidth, wh.pickinglocationdepth, connections))
                    {
                        cost             = Double.MaxValue;
                        infeasibledesign = true;
                        return;
                    }
                }

                //Check warehouse size here before doing any other calculations and if size is not fit then adjust it approprately
                int totalstoragelocations = wh.totalNumberOfLocations();
                if (increased > 0 && decreased > 0)                              //No exact number of locations but this is the smallest it can get then we stop
                {
                    if (wh.getSKUs().Count > totalstoragelocations)              //This check is necessary because last iteration it could have been decreased
                    {
                        wh.setArea(wh.area / options.warehouseadjustmentfactor); //Increase area
                        increased++;
                        finalize = true;
                    }
                    else if (wh.getSKUs().Count < totalstoragelocations || finalize == true)
                    {
                        warehousefit = true;
                        break;
                    }
                }
                if (wh.getSKUs().Count > totalstoragelocations)
                {
                    wh.setArea(wh.area / options.warehouseadjustmentfactor);//Increase area
                    increased++;
                }
                else if (wh.getSKUs().Count < totalstoragelocations)
                {
                    wh.setArea(wh.area * options.warehouseadjustmentfactor);//Decrease area
                    decreased++;
                }
                else if (wh.getSKUs().Count == totalstoragelocations)
                {
                    warehousefit = true;
                }
            } while (!warehousefit);

            if (!wh.usevisibilitygraph)//aisle centers method
            {
                wh.createImportantNodeShortestDistances();
                wh.locationShortestDistance();
            }
            else//visibility graph method
            {
                wh.createPolygonsandGraphNodes();
                wh.createVisibilityGraph();
                wh.fillGraphNodeDistances();
            }
            wh.pdTotalDistances();
            wh.totalDistances();
            wh.rankLocations(wh.avgTourLength);
            wh.colorOverall();
            //Use turnover based allocation method
            allocation al = new allocation(0);

            //If allocateSKUs return -1 then there is insufficient warehouse space, the design is infeasible, return positive infinite as a cost (death penalty)
            if (al.allocateSKUs(wh.getSKUs(), wh, 0) < 0)
            {
                cost = Double.MaxValue; infeasibledesign = true; return;
            }
            ;
            //Otherwise continue the calculations
            wh.setOrders(p_wh.getOrders());
            if (!wh.usevisibilitygraph) //Aisle centers method
            {
                if (p_computing == 0)   //Parallel computing
                {
                    var sums = new ConcurrentBag <double>();
                    Parallel.For(0, p_o, k =>
                    {
                        warehouse tmpwh        = wh;
                        List <order> tmporders = wh.getOrders();
                        routing rt             = new routing();
                        double tourcost        = 0;
                        bool LKHdoneonce       = false;
                        while (tourcost == 0)
                        {
                            if (p_optimal || LKHdoneonce)
                            {
                                tourcost = rt.tspOptSteiner(tmpwh, tmporders[k], k);
                                if (tourcost == 0)
                                {
                                    break;               //This means that tour cost is really zero (sometimes LKH returns 0 even though it should not)
                                }
                            }
                            else
                            {
                                tourcost    = rt.tspLKHSteiner(tmpwh, tmporders[k], k);
                                LKHdoneonce = true;
                            }
                        }
                        sums.Add(tourcost);
                    });
                    cost = sums.Sum() / p_o;
                }
                else if (p_computing == 1)//Distributed computing
                {
                    warehouse tmpwh = wh;
                    routing   rt    = new routing();
                    cost = rt.tspOptNetSteiner(tmpwh, p_o, p_socketservers, 0);
                }
            }
            else//Visibility graph method
            {
                if (p_computing == 0)//Parallel computing
                {
                    var sums = new ConcurrentBag <double>();
                    Parallel.For(0, p_o, k =>
                    {
                        warehouse tmpwh        = wh;
                        List <order> tmporders = wh.getOrders();
                        routing rt             = new routing();
                        double tourcost        = 0;
                        bool LKHdoneonce       = false;
                        while (tourcost == 0)
                        {
                            if (p_optimal || LKHdoneonce)
                            {
                                tourcost = rt.tspOptVisibility(tmpwh, tmporders[k], k);
                                if (tourcost == 0)
                                {
                                    break;               //This means that tour cost is really zero (sometimes LKH returns 0 even though it should not)
                                }
                            }
                            else
                            {
                                tourcost    = rt.tspLKHVisibility(tmpwh, tmporders[k], k);
                                LKHdoneonce = true;
                            }
                        }
                        sums.Add(tourcost);
                    });
                    cost = sums.Sum() / p_o;
                }
                else if (p_computing == 1)
                {
                    warehouse tmpwh = wh;
                    routing   rt    = new routing();
                    cost = rt.tspOptNetVisibility(tmpwh, p_o, p_socketservers, 0);
                }
            }
        }