/// <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 }
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); } } }