public override PointF MatchLocation(Fingerprint value, Match_Strategy strategy, double[] args) { switch(strategy) { case Match_Strategy.Single: { double min_dist = double.MaxValue; PointF best_loc = new PointF(); foreach (KeyValuePair<PointF, Fingerprint> kvp in this.loc_fingerprint_dict) { double dist = (kvp.Value as Fingerprint_S).CalcSimilarity(value as Fingerprint_S); if (dist < min_dist) { min_dist = dist; best_loc = kvp.Key; } } return best_loc; } case Match_Strategy.KNN: { if (args == null || args.Length < 1) throw new Exception("KNN匹配方法需要额外一个参数"); Dictionary<PointF, double> dists = new Dictionary<PointF, double>(); foreach (KeyValuePair<PointF, Fingerprint> kvp in this.loc_fingerprint_dict) { double dist = (kvp.Value as Fingerprint_S).CalcSimilarity(value as Fingerprint_S); dists[kvp.Key] = dist; } IOrderedEnumerable<KeyValuePair<PointF, double>> sorted = dists.OrderBy(x => x.Value); int k = (int)args[0]; int i = 0; KeyValuePair<PointF, double>[] NNs = new KeyValuePair<PointF, double>[k]; double sumr = 0; foreach(KeyValuePair<PointF, double> kvp in sorted) { if (i >= k) break; NNs[i] = kvp; sumr += 1 / kvp.Value; i++; } double mean_x = 0; double mean_y = 0; foreach(KeyValuePair<PointF, double> kvp in NNs) { mean_x += kvp.Key.X * ((1 / kvp.Value) / sumr); mean_y += kvp.Key.Y * ((1 / kvp.Value) / sumr); } return new PointF((float)mean_x, (float)mean_y); } } return new PointF(); }
//public override double CalcSimilarity(Fingerprint that) //{ // Fingerprint_S th = that as Fingerprint_S; // if (this.fingerprint.Length != th.fingerprint.Length) // return double.MaxValue; // List<double> tmp_this = new List<double>(); // List<double> tmp_that = new List<double>(); // for (int i = 0; i < this.fingerprint.Length; i++) // { // tmp_this.Add(this.fingerprint[i].Strength); // tmp_that.Add(th.fingerprint[i].Strength); // } // double[] this_s = tmp_this.ToArray(); // double[] that_s = tmp_that.ToArray(); // double r_s = new MathUtils.MathUtility().corrcoef(this_s, that_s); // return 1 / (r_s + 1); //} public override double CalcSimilarity(Fingerprint that) { Fingerprint_S th = that as Fingerprint_S; if (this.fingerprint.Length != th.fingerprint.Length) return double.MaxValue; double s_rmse = 0; for (int i = 0; i < this.fingerprint.Length; i++) { s_rmse += Math.Pow(this.fingerprint[i].Strength - th.fingerprint[i].Strength, 2); } s_rmse = Math.Sqrt(s_rmse / this.fingerprint.Length); return s_rmse * 1e6; }
public override Fingerprint Mean(Fingerprint[] prints) { int fp_len = prints.Length; int rec_len = (prints[0] as Fingerprint_S).fingerprint.Length; List<S> lst = new List<S>(); for (int i = 0; i < rec_len; i++) { double sum_s = 0; foreach (Fingerprint_S print in prints) { sum_s += print.fingerprint[i].Strength; } lst.Add(new S(sum_s / fp_len)); } return new Fingerprint_S(lst.ToArray()); }
private void GenerateFingerprintDataBase(object sender, DoWorkEventArgs e) { int avg_num = 5; object[] paras = (object[])e.Argument; int ray_num = (int)paras[0]; Transmitter.EMIT_OPTION emit_option = (Transmitter.EMIT_OPTION)paras[1]; Signal_Type signal_type = (Signal_Type)paras[2]; Noise_Type noise_type = (Noise_Type)paras[3]; double[] noise_params = (double[])paras[4]; int sample_cnt = (int)paras[5]; string file_name = (string)paras[6]; int total_pt_num = this.viz_rps.Map.GridPoints.Length; Transmitter tr = null; foreach (Transmitter trans in this.viz_rps.Map.Transmitters) tr = trans; if(tr == null) { e.Result = false; MessageBox.Show("地图上需要设置一个信号源以作为数据库所用信号源的参数参考。"); return; } Dictionary<PointF, Dictionary<Fingerprint_Name, Fingerprint>> dict = new Dictionary<PointF, Dictionary<Fingerprint_Name, Fingerprint>>(); for(int i = 0; i < total_pt_num; i++) { int cnt = 0; this.viz_rps.Map.ClearTransmitters(); Point loc = this.viz_rps.Map.GridPoints[i]; tr.Location = loc; this.viz_rps.Map.AddTransmitter(tr); Dictionary<Fingerprint_Name, Fingerprint[]> fps = new Dictionary<Fingerprint_Name,Fingerprint[]>(); for (int j = 0; j < Enum.GetNames(new Fingerprint_Name().GetType()).Length; j++) fps[(Fingerprint_Name)j] = new Fingerprint[avg_num]; while (cnt < avg_num) { Dictionary<Fingerprint_Name, Fingerprint> tmp = this.viz_rps.Map.RunSingleSimulation(ray_num, emit_option, signal_type, noise_type, noise_params, sample_cnt); foreach (KeyValuePair<Fingerprint_Name, Fingerprint> kvp in tmp) fps[kvp.Key][cnt] = kvp.Value; cnt++; this.bgwGenFDB.ReportProgress((int)((avg_num * i + cnt) / (double)(avg_num * total_pt_num) * 100)); System.Threading.Thread.Sleep(200); } Dictionary<Fingerprint_Name, Fingerprint> tmp_mean = new Dictionary<Fingerprint_Name, Fingerprint>(); foreach (KeyValuePair<Fingerprint_Name, Fingerprint[]> kvp in fps) { switch (kvp.Key) { case Fingerprint_Name.SA: tmp_mean.Add(kvp.Key, new Fingerprint_SA().Mean(kvp.Value)); break; case Fingerprint_Name.S: tmp_mean.Add(kvp.Key, new Fingerprint_S().Mean(kvp.Value));; break; default: tmp_mean.Add(kvp.Key, new Fingerprint().Mean(kvp.Value));; break; } } dict.Add(loc, tmp_mean); } FingerprintDataBase fdb = new FingerprintDataBase(dict, this.viz_rps.Map); System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); FileStream fs = new FileStream(file_name, FileMode.Create, FileAccess.Write, FileShare.None); formatter.Serialize(fs, fdb); fs.Close(); e.Result = true; }
/// <summary> /// 计算多个指纹的平均值 /// </summary> /// <param name="prints"></param> /// <returns></returns> public virtual Fingerprint Mean(Fingerprint[] prints) { return null; }
/// <summary> /// 计算与另一个指纹的相似度 /// </summary> /// <param name="that"></param> /// <returns></returns> public virtual double CalcSimilarity(Fingerprint that) { return double.MaxValue; }
/// <summary> /// 返回最匹配的位置坐标 /// </summary> /// <param name="value"></param> public PointF MatchLocation(Fingerprint value, Match_Strategy strategy, double[] args) { switch (strategy) { case Match_Strategy.Single: { double min_dist = double.PositiveInfinity; PointF best_loc = new PointF(); foreach (KeyValuePair<PointF, Dictionary<Fingerprint_Name, Fingerprint>> kvp in this.loc_fingerprint_dict) { double dist = double.PositiveInfinity; switch(value.Name) { case Fingerprint_Name.SA: dist = (kvp.Value[value.Name] as Fingerprint_SA).CalcSimilarity(value as Fingerprint_SA); break; case Fingerprint_Name.S: dist = (kvp.Value[value.Name] as Fingerprint_S).CalcSimilarity(value as Fingerprint_S); break; } if (dist < min_dist) { min_dist = dist; best_loc = kvp.Key; } } return best_loc; } case Match_Strategy.KNN: { if (args == null || args.Length < 1) throw new Exception("KNN匹配方法需要额外一个参数"); Dictionary<PointF, double> dists = new Dictionary<PointF, double>(); foreach (KeyValuePair<PointF, Dictionary<Fingerprint_Name, Fingerprint>> kvp in this.loc_fingerprint_dict) { double dist = double.PositiveInfinity; switch(value.Name) { case Fingerprint_Name.SA: dist = (kvp.Value[value.Name] as Fingerprint_SA).CalcSimilarity(value as Fingerprint_SA); break; case Fingerprint_Name.S: dist = (kvp.Value[value.Name] as Fingerprint_S).CalcSimilarity(value as Fingerprint_S); break; } dists[kvp.Key] = dist; } IOrderedEnumerable<KeyValuePair<PointF, double>> sorted = dists.OrderBy(x => x.Value); int k = (int)args[0]; int i = 0; KeyValuePair<PointF, double>[] NNs = new KeyValuePair<PointF, double>[k]; double sumr = 0; foreach (KeyValuePair<PointF, double> kvp in sorted) { if (double.IsNaN(kvp.Value)) continue; if (i >= k) break; NNs[i] = kvp; sumr += 1 / kvp.Value; i++; } double mean_x = 0; double mean_y = 0; foreach (KeyValuePair<PointF, double> kvp in NNs) { mean_x += kvp.Key.X * ((1 / kvp.Value) / sumr); mean_y += kvp.Key.Y * ((1 / kvp.Value) / sumr); } return new PointF((float)mean_x, (float)mean_y); } case Match_Strategy.KNN_HC: { if (args == null || args.Length < 1) throw new Exception("KNN匹配方法需要额外一个参数"); Dictionary<PointF, double> dists = new Dictionary<PointF, double>(); foreach (KeyValuePair<PointF, Dictionary<Fingerprint_Name, Fingerprint>> kvp in this.loc_fingerprint_dict) { double dist = double.PositiveInfinity; switch (value.Name) { case Fingerprint_Name.SA: dist = (kvp.Value[value.Name] as Fingerprint_SA).CalcSimilarity(value as Fingerprint_SA); break; case Fingerprint_Name.S: dist = (kvp.Value[value.Name] as Fingerprint_S).CalcSimilarity(value as Fingerprint_S); break; } dists[kvp.Key] = dist; } IOrderedEnumerable<KeyValuePair<PointF, double>> sorted = dists.OrderBy(x => x.Value); int k = (int)args[0]; int i = 0; List<MathUtils.MathUtility.Cluster> clusters = new List<MathUtils.MathUtility.Cluster>(); Dictionary<PointF, double> NNs = new Dictionary<PointF,double>(); foreach (KeyValuePair<PointF, double> kvp in sorted) { if (double.IsNaN(kvp.Value)) continue; if (i >= k) break; NNs.Add(kvp.Key, kvp.Value); clusters.Add(new MathUtils.MathUtility.Cluster(new List<PointF>() { kvp.Key })); i++; } new MathUtils.MathUtility().HierachicalClustering_InPlace(clusters, 2); MathUtils.MathUtility.Cluster cluster = clusters.OrderByDescending(x => x.PointNum).First(); double sum_r = 0; double wx_sum = 0; double wy_sum = 0; foreach(PointF pt in cluster.point_list) { sum_r += 1 / NNs[pt]; wx_sum += pt.X * 1 / NNs[pt]; wy_sum += pt.Y * 1 / NNs[pt]; } return new PointF((float)(wx_sum / sum_r), (float)(wy_sum / sum_r)); } } return new PointF(); }
//public override double CalcSimilarity(Fingerprint that) //{ // Fingerprint_SA th = that as Fingerprint_SA; // if (this.fingerprint.Length != th.fingerprint.Length) // return double.MaxValue; // List<double> tmp_this = new List<double>(); // List<double> tmp_that = new List<double>(); // for (int i = 0; i < this.fingerprint.Length; i++) // { // tmp_this.Add(this.fingerprint[i].Strength); // tmp_that.Add(th.fingerprint[i].Strength); // } // double[] this_s = tmp_this.ToArray(); // double[] that_s = tmp_that.ToArray(); // double r_s = new MathUtils.MathUtility().corrcoef(this_s, that_s); // tmp_this.Clear(); // tmp_that.Clear(); // for (int i = 0; i < this.fingerprint.Length; i++) // { // tmp_this.Add(this.fingerprint[i].AOA / 180 * Math.PI); // tmp_that.Add(th.fingerprint[i].AOA / 180 * Math.PI); // } // double[] this_a = tmp_this.ToArray(); // double[] that_a = tmp_that.ToArray(); // double r_a = new MathUtils.MathUtility().corrcoef(this_a, that_a); // return 1 / ((r_s + r_a) / 2 + 1); //} //public override double CalcSimilarity(Fingerprint that) //{ // Fingerprint_SA th = that as Fingerprint_SA; // if (this.fingerprint.Length != th.fingerprint.Length) // return double.MaxValue; // double s_rmse = 0; // double aoa_rmse = 0; // for (int i = 0; i < this.fingerprint.Length; i++) // { // s_rmse += Math.Pow(this.fingerprint[i].Strength - th.fingerprint[i].Strength, 2); // aoa_rmse += Math.Pow(new MathUtils.MathUtility().diff_degree(this.fingerprint[i].AOA, th.fingerprint[i].AOA), 2); // } // s_rmse = Math.Sqrt(s_rmse / this.fingerprint.Length); // aoa_rmse = Math.Sqrt(aoa_rmse / this.fingerprint.Length) / 180 * Math.PI; // return s_rmse * 1e2 + aoa_rmse; //} public override double CalcSimilarity(Fingerprint that) { Fingerprint_SA th = that as Fingerprint_SA; if (this.fingerprint.Length != th.fingerprint.Length) return double.MaxValue; double total_s_this = 0; double total_s_that = 0; for (int i = 0; i < this.fingerprint.Length; i++) { total_s_this += this.fingerprint[i].Strength; total_s_that += th.fingerprint[i].Strength; } double rmse = 0; for (int i = 0; i < this.fingerprint.Length; i++) { double this_c = this.fingerprint[i].Strength * this.fingerprint[i].AOA / total_s_this; double that_c = th.fingerprint[i].Strength * th.fingerprint[i].AOA / total_s_that; rmse += Math.Pow(new MathUtils.MathUtility().diff_degree(this_c, that_c), 2); } rmse = Math.Sqrt(rmse / this.fingerprint.Length); return rmse; }
public override Fingerprint Mean(Fingerprint[] prints) { int fp_len = prints.Length; int rec_len = (prints[0] as Fingerprint_SA).fingerprint.Length; List<SA> lst = new List<SA>(); for (int i = 0; i < rec_len; i++) { double sum_s = 0; double sum_a = 0; foreach (Fingerprint_SA print in prints) { sum_s += print.fingerprint[i].Strength; sum_a += double.IsInfinity(print.fingerprint[i].AOA) ? 0 : print.fingerprint[i].AOA; } double mean_s = sum_s / fp_len; double mean_a = sum_a == 0 ? double.NegativeInfinity : sum_a / fp_len; lst.Add(new SA(mean_s, mean_a)); } return new Fingerprint_SA(lst.ToArray()); }