private static List <List <double> > evaluateFitness(Plot plot, ApartmentGeneratorBase ag, Target target, List <ParameterSet> gene, double fitnessFactor, bool previewOn) { List <List <double> > result = new List <List <double> >(); List <double> grossAreaRatio = new List <double>(); List <double> parkinglotRatio = new List <double>(); List <double> targetAccuracy = new List <double>(); List <double> axisAccuracy = new List <double>(); bool drawSomeThing = false; int i = 0; var timer = new System.Threading.Timer((e) => { drawSomeThing = true; } , drawSomeThing, TimeSpan.Zero, TimeSpan.FromMilliseconds(1000)); List <Apartment> agOutToDrawList = new List <Apartment>(); List <double> agOutToDrawGrossAreaList = new List <double>(); for (i = 0; i < gene.Count(); i++) { Apartment tempOutput = ag.generator(plot, gene[i], target); grossAreaRatio.Add(tempOutput.GetGrossAreaRatio()); //targetAccuracy.Add(tempOutput.GetTargetAccuracy()); parkinglotRatio.Add(tempOutput.GetParkingScore()); axisAccuracy.Add(tempOutput.GetAxisAccuracy()); TuringAndCorbusierPlugIn.InstanceClass.page3.currentProgressFactor += 1; TuringAndCorbusierPlugIn.InstanceClass.page3.updateProGressBar(TuringAndCorbusierPlugIn.InstanceClass.page3.currentProgressFactor.ToString() + "/" + TuringAndCorbusierPlugIn.InstanceClass.page3.currentWorkQuantity.ToString() + " 진행중"); if (previewOn) { agOutToDrawList.Add(tempOutput); //agOutToDrawGrossAreaList.Add(tempOutput.GetGrossAreaRatio()); if (drawSomeThing) { TuringAndCorbusierPlugIn.InstanceClass.page3.preview(agOutToDrawList.Last()); Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); Rhino.RhinoApp.Wait(); agOutToDrawList.Clear(); agOutToDrawGrossAreaList.Clear(); drawSomeThing = false; } } } double MaxFAR = TuringAndCorbusierPlugIn.InstanceClass.page1Settings.MaxFloorAreaRatio; //법정 용적률에 근접한 유전자가 가장 높은 값 받음, // -0 ~ -5 최대값 받음 //넘어가면 * 0.01 포인트 마이너스 //낮으면 *0.1포인트 마이너스 List <double> points = new List <double>(); for (int r = 0; r < grossAreaRatio.Count; r++) { double point = 0; if (grossAreaRatio[r] < MaxFAR && grossAreaRatio[r] > MaxFAR - 5) { point = 1 + (5 - (MaxFAR - grossAreaRatio[r])) / MaxFAR; } else if (grossAreaRatio[r] > MaxFAR) { point = 1 - (grossAreaRatio[r] - MaxFAR) / MaxFAR / 10; } else { point = 1 - (MaxFAR - grossAreaRatio[r]) / MaxFAR; } points.Add(point); } List <double> tempGAR = new List <double>(grossAreaRatio); RhinoList <double> FARList = new RhinoList <double>(tempGAR); //FARList.Sort(points.ToArray()); //points.Sort(); double Cworst = FARList.First; double Cbest = FARList.Last; double k = fitnessFactor; List <double> fitness = new List <double>(); //double Cworst = tempGAR[0]; //double Cbest = tempGAR[gene.Count - 1]; //double k = fitnessFactor; //List<double> fitness = new List<double>(); double parkingWeight = 0.3; double CworstR = parkinglotRatio.Min(); double CbestR = parkinglotRatio.Max(); double targetWeight = 0.4; //double CworstT = targetAccuracy.Min(); //double CbestT = targetAccuracy.Max(); //fitnessvalue rate //연면적 1 : 주차율(?) 0.3 : 유닛정확도 : 0.4 //for test //string url = @"C://Users//user//Desktop//test"; //System.IO.DirectoryInfo dinfo = new System.IO.DirectoryInfo(url); //string filename = "//garojutacklogV2" + (dinfo.GetFiles().Length + 1).ToString() + ".csv"; //System.IO.FileStream fs = new System.IO.FileStream(url + filename, System.IO.FileMode.CreateNew); //fs.Close(); //fs.Dispose(); //System.IO.StreamWriter w = new System.IO.StreamWriter(fs.Name); //string column = "FAR" + "," + "Floors" + "," + "FARPoint" + "," + "ParkingPoint" + "," + "AxisPoint" + "," + "Sum" + "," + "Use1F" + ",UseSetback"; //w.WriteLine(column); for (int j = 0; j < gene.Count; j++) { double farfitnessVal = points[j] * 10; double parkkingfitnessVal = parkinglotRatio[j]; double axisfitnessVal = axisAccuracy[j]; //double farfitnessVal = ((grossAreaRatio[j] - Cbest) * (k - 1) / k + (Cbest - Cworst) + 0.01) / (Cbest - Cworst + 0.01); //double parkingval = ((parkinglotRatio[j] - CbestR) * (k - 1) / k + (CbestR - CworstR) + 0.01) / (CbestR - CworstR + 0.01) * parkingWeight; //double targetval = ((targetAccuracy[j] - CbestT) * (k - 1) / k + (CbestT - CworstT) + 0.01) / (CbestT - CworstT + 0.01) * targetWeight; //firstfloor test double firstfloorBonus = 0; //if (gene[j].using1F) // firstfloorBonus = 1000; //setback test double setbackBonus = 0; //if (gene[j].setback) // setbackBonus = 1000; fitness.Add(farfitnessVal + parkkingfitnessVal + axisfitnessVal + setbackBonus + firstfloorBonus); //for test //string format = grossAreaRatio[j].ToString() + "," + gene[j].Stories + "," + farfitnessVal + "," + parkkingfitnessVal + "," + axisfitnessVal + "," + (farfitnessVal + parkkingfitnessVal + axisfitnessVal).ToString() + "," + gene[j].using1F.ToString() + "," + gene[j].setback.ToString(); //w.WriteLine(format); } //for test //w.Close(); //w.Dispose(); //tempGAR.Reverse(); //fitness.Reverse(); //FARList.Reverse(); result.Add(fitness); result.Add(FARList.Select(n => n).ToList()); double maxfar = FARList.Max(); double maxfitness = fitness.Max(); TuringAndCorbusierPlugIn.InstanceClass.page3.updateProGressBar(TuringAndCorbusierPlugIn.InstanceClass.page3.currentProgressFactor.ToString() + "/" + TuringAndCorbusierPlugIn.InstanceClass.page3.currentWorkQuantity.ToString() + " 완료"); return(result); //or, return nested list, containing gross area ratio. }
public static List <Apartment> giantAnteater(Plot plot, ApartmentGeneratorBase ag, Target target, bool previewOn) { double mutationProbability = ag.GAParameterSet[0]; double elitismPercentage = ag.GAParameterSet[1]; double initialBoost = ag.GAParameterSet[2]; int population = (int)ag.GAParameterSet[3]; int maxGen = (int)ag.GAParameterSet[4]; double fitnessFactor = ag.GAParameterSet[5]; double mutationFactor = ag.GAParameterSet[6]; //Initialize Minimum and Maximum value double[] tempMaxInput = ag.MaxInput.Clone() as double[]; double[] tempMinInput = ag.MinInput.Clone() as double[]; //create initial genes Random myRandom = new Random((int)DateTime.Now.Ticks); double goodAngle = maxRectDirection(plot); //double goodAngle = Math.PI * 152 / 180; List <ParameterSet> offspringGenes = new List <ParameterSet>(); //for (int i = 0; i < initialBoost; i++) //{ // CoreType tempCoreType = ag.GetRandomCoreType(); // double[] oneGene = new double[ag.MinInput.Length]; // //if (ag.IsCoreProtrude) // // tempMaxInput[2] = tempCoreType.GetDepth(); // for (int j = 0; j < ag.MinInput.Length; j++) // { // if (i % 2 == 0 && j == 3 && ag.GetType() == typeof(AG1)) // { // oneGene[j] = goodAngle; // } // else // { // double parameterForGene = (tempMaxInput[j] - tempMinInput[j]) * myRandom.NextDouble() + tempMinInput[j]; // oneGene[j] = parameterForGene; // } // oneGene[0] = Math.Floor(oneGene[0]); // oneGene[1] = Math.Floor(oneGene[1]); // } // ParameterSet a = new ParameterSet(oneGene, ag.GetType().ToString(), tempCoreType); // offspringGenes.Add(a); //} double otherAngles = population * initialBoost;//(population - 1) * initialBoost; for (int i = 0; i < (int)otherAngles; i++) { CoreType tempCoreType = ag.GetRandomCoreType(); double[] oneGene = new double[ag.MinInput.Length]; //if (ag.IsCoreProtrude) // tempMaxInput[2] = tempCoreType.GetDepth(); for (int j = 0; j < ag.MinInput.Length; j++) { if (/*i % 2 == 0 &&*/ j == 3 && ag.GetType() == typeof(AG1)) { double parameterForGene = ((goodAngle + Math.PI / 2 * (i % 4) / 2) % (Math.PI * 2) + Math.PI * ((int)(i / 4) % 2) % (Math.PI * 2)); //oneGene[j] = parameterForGene; //double mainAngle = Math.PI * i / otherAngles; //oneGene[j] = mainAngle; oneGene[j] = parameterForGene; } else { double parameterForGene = (tempMaxInput[j] - tempMinInput[j]) * myRandom.NextDouble() + tempMinInput[j]; //width - 100씩 if (j == 2) { parameterForGene = Math.Round(parameterForGene / 100) * 100; } oneGene[j] = parameterForGene; } oneGene[0] = Math.Floor(oneGene[0]); oneGene[1] = Math.Floor(oneGene[1]); } ParameterSet a = new ParameterSet(oneGene); offspringGenes.Add(a); } //initializing end condition bool endCondition = true; //start genetic algorithm int genCount = 0; ParameterSet bestGene = offspringGenes[0]; while (endCondition) { //evaluate fitness` List <List <double> > evaluation = new List <List <double> >(evaluateFitness(plot, ag, target, offspringGenes, fitnessFactor, previewOn)); List <double> fitnessValues = new List <double>(evaluation[0]); //sort genes and fitness values RhinoList <ParameterSet> myRhinoList = new RhinoList <ParameterSet>(offspringGenes); myRhinoList.Sort(fitnessValues.ToArray()); myRhinoList.Reverse(); fitnessValues.Sort(); fitnessValues.Reverse(); offspringGenes = myRhinoList.ToList(); var radcheck = offspringGenes.Select(n => n.Parameters[3]); /* * //write * Rhino.RhinoApp.WriteLine(genCount.ToString()); * Rhino.RhinoApp.WriteLine(evaluation[1][0].ToString()); * Rhino.RhinoApp.WriteLine(evaluation[1][offspringGenes.Count-1].ToString()); * ParameterSet geneToShow = offspringGenes[0]; * * for (int i = 0; i < geneToShow.Parameters.Length; i++) * { * Rhino.RhinoApp.WriteLine(geneToShow.Parameters[i].ToString()); * } */ //create new generation List <ParameterSet> tempGenes = new List <ParameterSet>(); //Add elites to new generation int eliteNum = (int)(population * elitismPercentage); for (int i = 0; i < eliteNum; i++) { tempGenes.Add(offspringGenes[i]); } //crossover & mutation for (int i = 0; i < population - eliteNum; i++) { ParameterSet newOffspring = crossover(offspringGenes, fitnessValues, (int)myRandom.Next(0, int.MaxValue), ag.GetType().ToString()); if (myRandom.NextDouble() < mutationProbability) { newOffspring = mutation(newOffspring, ag, mutationFactor, (int)myRandom.Next(0, int.MaxValue)); } tempGenes.Add(newOffspring); } offspringGenes = tempGenes; genCount += 1; if (genCount == maxGen) { endCondition = false; } GC.Collect(); //Rhino.RhinoApp.Wait(); //finalize before end if (endCondition == false) { //evaluate fitness evaluation = new List <List <double> >(evaluateFitness(plot, ag, target, offspringGenes, fitnessFactor, previewOn)); fitnessValues = new List <double>(evaluation[0]); //sort genes and fitness values myRhinoList = new RhinoList <ParameterSet>(offspringGenes); myRhinoList.Sort(fitnessValues.ToArray()); myRhinoList.Reverse(); fitnessValues.Sort(); fitnessValues.Reverse(); offspringGenes = myRhinoList.ToList(); bestGene = offspringGenes[0]; } Rhino.RhinoApp.Wait(); } //best 1 Apartment bestOutput = ag.generator(plot, bestGene, target); return(new Apartment[] { bestOutput }.ToList()); //best 5 //var uniqueGenes = offspringGenes.Distinct(); //Apartment[] bestOutputs = offspringGenes.Take(5).Select(n => ag.generator(plot, n, target)).ToArray(); //return bestOutputs.ToList(); //best 10 //var uniqueGenes = offspringGenes.Distinct(); //Apartment[] bestOutputs = offspringGenes.Take(10).Select(n=>ag.generator(plot, n, target)).ToArray(); //return new Apartment[] { bestOutput }.ToList(); //return bestOutputs.ToList(); //all Apartment[] bestOutputs = offspringGenes.Select(n => ag.generator(plot, n, target)).ToArray(); return(bestOutputs.ToList()); if (bestOutput.ParameterSet == null) { return(FinalizeApartment.finalizeAGoutput(bestOutput, TuringAndCorbusierPlugIn.InstanceClass.page1Settings.MaxFloorAreaRatio, TuringAndCorbusierPlugIn.InstanceClass.page1Settings.MaxBuildingCoverage, false)); } if (bestOutput.ParameterSet.Parameters != null) { List <Apartment> output = FinalizeApartment.finalizeAGoutput(bestOutput, TuringAndCorbusierPlugIn.InstanceClass.page1Settings.MaxFloorAreaRatio, TuringAndCorbusierPlugIn.InstanceClass.page1Settings.MaxBuildingCoverage, false); bool IsSatisfyingLegalParking = false; List <Apartment> satisFyingLegalParkingOutput = new List <Apartment>(); foreach (Apartment i in output) { if (i.GetLegalParkingLotOfCommercial() + i.GetLegalParkingLotofHousing() < i.ParkingLotOnEarth.GetCount() + i.ParkingLotUnderGround.Count) { satisFyingLegalParkingOutput.Add(i); IsSatisfyingLegalParking = true; } } if (IsSatisfyingLegalParking == false) { targetError tempErrorMessage = new targetError(); List <Apartment> tempNewOutput = tempErrorMessage.showDialogAndReturnValue(ag, plot, bestGene, target, output); bool tempSatisfyingLegalParking = false; List <Apartment> tempSatisFyingLegalParkingOutput = new List <Apartment>(); foreach (Apartment i in tempNewOutput) { if (i.GetLegalParkingLotOfCommercial() + i.GetLegalParkingLotofHousing() < i.ParkingLotOnEarth.GetCount() + i.ParkingLotUnderGround.Count) { tempSatisfyingLegalParking = true; tempSatisFyingLegalParkingOutput.Add(i); } } if (tempSatisfyingLegalParking == false) { System.Windows.MessageBox.Show("선택한 설계로 법정 주차대수를 만족하기 어려운 대지입니다."); return(output); } else { return(tempSatisFyingLegalParkingOutput); } } else { return(output); } } else { System.Windows.MessageBox.Show(CommonFunc.GetApartmentType(ag.GetAGType) + " 타입 설계에 적합하지 않은 대지입니다."); } return(FinalizeApartment.finalizeAGoutput(bestOutput, TuringAndCorbusierPlugIn.InstanceClass.page1Settings.MaxFloorAreaRatio, TuringAndCorbusierPlugIn.InstanceClass.page1Settings.MaxBuildingCoverage, false)); }