} // Detect /// <summary> /// Совершенствует механизм выявления сходства путем обучения. /// </summary> /// <param name="affinity">Эталонное значение степени сходства объектов, указанных в последнем вызове метода Detect.</param> public virtual void Learn(Affinity affinity) { if (DetectedAffinity == null) { throw new AffinityDetectorException("Обучение детектора сходства возможно только после проведения нулевой итерации сравнения объектов."); } // В базовой абстрактной реализации никакие методики обучения не поддерживаются. } // Learn
} // Affinity /// <summary> /// Определяет равенство степеней сходства по их значениям. /// </summary> /// <param name="obj">Степерь сходства с которой производится сравнение.</param> /// <returns>Результат совпадения текущей степень сходства с указнной.</returns> public override bool Equals(object obj) { bool result = false; if ((obj != null) && (obj is Affinity)) { Affinity affinity = (Affinity)obj; result = Value.Equals(affinity.Value) && Reliability.Equals(affinity.Reliability); } return(result); } // Equals
} // Done /// <summary> /// Определяет степень сходства двух заданных объектов. /// </summary> /// <param name="features1">Совокупность реперных характеристик одного из сравниваемых объектов.</param> /// <param name="features2">Совокупность реперных характеристик другого сравниваемого объекта.</param> /// <returns>Степень сходства заданных объектов.</returns> public virtual Affinity Detect(IEnumerable <T> features1, IEnumerable <T> features2) { if (CorrelationMatrix == null) { throw new AssertException("Отсутствует матрица корреляций, т.к. не был вызван метод Init базового класса детектора сходства."); } if (AffinityBlockBuilder == null) { throw new AffinityDetectorException("В свойстве AffinityBlockBuilder не задан метод разбиения реперных характеристик сравниваемых объектов на устойчивые блоки реперных характеристик."); } if (AffinityBlockCorrelator == null) { throw new AffinityDetectorException("В свойстве AffinityBlockCorrelator не задан метод определения степени корреляции между устойчивыми блоками реперных характеристик сравниваемых объектов."); } AffinityBlocks1 = AffinityBlockBuilder(features1); AffinityBlocks2 = AffinityBlockBuilder(features2); int size = 0; int diffs = 0; double reliability = 0; while (AffinityBlocks1.MoveNext() && AffinityBlocks2.MoveNext()) { Correlation correlation = AffinityBlockCorrelatorInvoke(AffinityBlocks1.Current, AffinityBlocks2.Current); if (correlation.Importance > 0.5) { // Учитываем только значимые блоки и пропускаем малозначительные, например, относящиеся к фону. if (correlation.Value > 0.5) { // Соответствующие устойчивые блоки реперных характеристик коррелируют между собой. reliability = reliability + correlation.Value; } else { // Соответствующие устойчивые блоки реперных характеристик не коррелируют между собой. diffs++; } size++; } } if (size == diffs) { // Сравниваемые объекты гарантированно не похожи между собой. reliability = 1; DetectedAffinity = new Affinity(0, reliability); } else { // Сравниваемые объекты имеют некоторое сходство по своим реперным характеристикам. reliability = reliability / (size - diffs); double affinity = 1 - (double)diffs / (double)size; DetectedAffinity = new Affinity(affinity, reliability); } return(DetectedAffinity); } // Detect