private void AdaptWeights(List <Site> Sites) { CurrentMinNegativeWeight = 0; foreach (Site s in Sites) { double area_current = s.ClipPolyon.GetArea(); double area_target = s.Attribute / SumAttr * Bound.GetArea(); double radius_current = Math.Sqrt(area_current / Math.PI); double radius_target = Math.Sqrt(area_target / Math.PI); double deltaCircle = radius_current - radius_target; double f_adapt = (area_target / area_current); if ((f_adapt > 1.1 && s.LastF < 0.9) || (f_adapt < 0.9 && s.LastF > 1.1)) { f_adapt = Math.Sqrt(f_adapt); } if (f_adapt < 1.1 && f_adapt > 0.9 && s.Weight != 1) { f_adapt = Math.Sqrt(f_adapt); } if (s.Weight < 10) { f_adapt = f_adapt * f_adapt; } if (s.Weight > 10) { f_adapt = Math.Sqrt(f_adapt); } s.LastF = f_adapt; s.Weight *= f_adapt; if (s.Weight < Eps) { double radius_new2 = Math.Sqrt(s.Weight) - deltaCircle; if (radius_new2 < 0) { s.Weight = -(radius_new2 * radius_new2); if (s.Weight < CurrentMinNegativeWeight) { CurrentMinNegativeWeight = s.Weight; } } } } if (CurrentMinNegativeWeight < 0) { CurrentMinNegativeWeight = -CurrentMinNegativeWeight; foreach (Site s in Sites) { s.Weight += CurrentMinNegativeWeight + Eps; } } FixWeights(); }
private void SetSiteProcess(Random rand, Int32[] indices, double[] unseted, double[] boundrect) { int count = unseted.Count <double>(); double x, y; Vector p; do { x = boundrect[0] + (boundrect[1] - boundrect[0]) * rand.NextDouble(); y = boundrect[2] + (boundrect[3] - boundrect[2]) * rand.NextDouble(); p = new Vector(x, y); } while (!Bound.IsInPolygon(p)); Sites[indices[count - 1]] = new Site(x, y, unseted[count - 1], Eps); if (count == 1) { return; } double maxattr = 0.3 * unseted[count - 1]; double sumattr = unseted[0]; int start = 0; for (int i = 1; i < count; i++) { sumattr += unseted[i]; if (sumattr > maxattr || i == count - 1) { int length = i - start; Int32[] tmp_indices = new Int32[length]; double[] tmp_unseted = new double[length]; for (int j = 0; j < length; j++) { tmp_indices[j] = indices[start + j]; tmp_unseted[j] = unseted[start + j]; } //double x, y; //Vector p; do { x = boundrect[0] + (boundrect[1] - boundrect[0]) * rand.NextDouble(); y = boundrect[2] + (boundrect[3] - boundrect[2]) * rand.NextDouble(); p = new Vector(x, y); } while (!Bound.IsInPolygon(p)); double arearoothalf = Math.Sqrt(sumattr / SumAttr * Bound.GetArea()) / 2; double[] tmp_boundrect = new double[4]; tmp_boundrect[0] = x - arearoothalf; tmp_boundrect[1] = x + arearoothalf; tmp_boundrect[2] = y - arearoothalf; tmp_boundrect[3] = y + arearoothalf; SetSiteProcess(rand, tmp_indices, tmp_unseted, tmp_boundrect); start = i; sumattr = unseted[i]; } } }
public double GetError(List <Site> Sites) { double Error = 0; foreach (Site s in Sites) { double area_current = s.ClipPolyon.GetArea(); double area_target = s.Attribute / SumAttr * Bound.GetArea(); Error = Math.Max(Math.Abs(area_current - area_target) / area_target, Error); //Error = Math.Max(Math.Abs(area_current - area_target) / Bound.get_Area(), Error); } return(Error); }