2015-02-14 5 views
-2

Я пытаюсь создать упорядоченную карту, которая использует сравнительные сравнения расстояний. Однако способ ConcurrentSkipListMap (который я использую в данный момент) интерпретирует сравнения с компаратором, делает сравнение относительных расстояний невозможным. Существуют ли какие-либо структуры данных, которые позволяют использовать карты, такие как операции с ключом и относительный порядок?Компаратор Java с относительным расстоянием

Когда я говорю о сравнительных сравнениях, я имею в виду, что два значения нельзя сравнивать напрямую, но их нужно рассматривать с помощью контрольной точки. Подумайте, как эвклидово расстояние.

РЕДАКТИРОВАТЬ:

, например: при сравнении двоичных чисел 0011 и 1100 хочу сказать, один больше, чем другие на основе расстояния Хемминга (количество 1 битов в XOR двух чисел, эквивалентно, расстояние между двумя узлами в графе гиперкуба), очевидно, мне нужна контрольная точка для сравнения расстояния, поэтому я выбираю 0000 в качестве ссылки. Расстояние от 0011 до 0000 равно 2, а расстояние от 1100 до 0000 равно 2, однако 1100 не равно 0011. Я бы хотел сказать, что они имеют одинаковое относительное расстояние, но не равны. В конечном итоге будет отсортирован список этих чисел. Для справки 0000, в порядке возрастания, мы могли бы иметь 1000, 0100, 1100, 1001, 0011, 1110, 1101, 1111.

edit2, почему я не могу использовать компаратор:

Фактор для этого общего порядка: {(x, y) такой, что c.compare (x, y) == 0}.

Из сравнения следует, что отношение является отношением эквивалентности на S и что наложенный порядок является полным порядком на S. Когда мы говорим, что упорядочение, налагаемое с на S, согласуется с равенствами, мы имеем в виду, что фактором для упорядочения является отношение эквивалентности, определяемое методом (объектами) объектов: equals (Object): {(x, y) такое, что x.equals (y)}.

http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

+1

Пример ввода и вывода будет полезен. – khelwood

+1

Можете ли вы опубликовать код, который показывает, что вы пытаетесь сделать, даже если он не работает? Или пример входов и выходов, как сказал хелвуд. – immibis

+0

Зачем вам устанавливать такой заказ? Может ли другая структура данных, например [4-d tree] (http://en.wikipedia.org/wiki/K-d_tree), работать лучше для вашей цели? Если вы работаете с 4-мерной геометрией, которая может иметь больше смысла, чем отсортированный список. –

ответ

3

Вы всегда можете различать экземпляры, имеющие одинаковое расстояние до ссылочного номера, путем дальнейшего сравнения, когда расстояния одинаковы. Например, если вы представлять числа в Integer с:

public int compare(Integer i1, Integer i2) { 
     Integer r1 = hammingDistanceToReference(i1); 
     Integer r2 = hammingDistanceToReference(i2); 

     if (!r1.equals(r2)) 
      return r1.compareTo(r2); 

     return i1.compareTo(i2); 
    } 

Таким образом, цифры, которые имеют различное расстояние Хэмминга до ссылки будут упорядочены должным образом, и те, которые имеют такое же расстояние Хэмминга будет также полностью упорядочена.

+0

Я рассматривал этот подход, но я хотел бы посмотреть, могу ли я избежать его, если он действительно не нужен. – kag0

+1

Учитывая, что это, пожалуй, самый чистый и простой подход, я не уверен, чего вы бы точно избежали ... –

+0

Также 'Comparator.comparingInt (Integer :: bitCount). ThenComparing (Integer :: compareTo)'. – Radiodef

-2

Несколько Set реализаций позволяют компаратор, который не согласуется с равными. Если ConcurrentSkipListMap не делает, то ваши варианты должны использовать тот, который делает или использует неупорядоченную коллекцию, а затем сортирует ее вручную при вставке с использованием Collection.sort.

Вот пример создания Comparator (несовместимым с равными):

class Point { 
    int distanceTo(Point other) { 
     ... 
    } 

    Comparator<Point> distanceComparator() { 
     return (point1, point2) -> distanceTo(point1) - distanceTo(point2); 
    } 
} 

List<Point> points; 
Point fixedPoint; 
Collections.sort(points, fixedPoints.distanceComparator()); 

Это теперь будет сортировать points расстоянием до fixedPoint. В качестве альтернативы, по соображениям эффективности, вы можете использовать тот факт, что набор уже был отсортирован для правильной позиции при добавлении новых позиций:

Вы ссылаетесь на документацию для Comparator, в частности определение теории групп для группы связь. Ключевым условием является то, что если два элемента: equals, они должны возвращать 0 при сравнении. Однако, наоборот, это не так: если два элемента возвращают 0 при сравнении, это не обязательно означает, что они равны equals. Существует много случаев, когда порядок двух элементов не определен. Простым примером является порядок словаря, игнорирующий случай. В этой ситуации слова «Foobar», «foobar» и «FOOBAR» все «равны» относительно порядка.

Об этом говорится в документации как «несовместимая по отношению к равным».Например, в документации для SortedSet сказано: «Поведение сортированного набора хорошо определено, даже если его порядок не соответствует равным, он просто не выполняет общий контракт интерфейса Set». Это неверно для всех реализаций Set.

+0

Компаратор - это то, что я изначально использовал, однако, как я уже упоминал, контракт для компаратора не позволяет использовать этот тип вещей (в моем случае, используя ConcurrentSkipListMap). – kag0

+0

Я не специалист по теории математических групп. Но мое понимание вашей цитаты состоит в том, что группа эквивалентности для компаратора определяется элементами, которые приводят к 0 при сравнении. Или в моем примере точки, которые равны расстоянию от неподвижной точки. Я не вижу, как это исключает использование этого типа компаратора. На самом деле он часто используется в кодировании, поэтому я подозреваю, что вы неправильно понимаете документацию. – sprinter

+0

Я также не эксперт в теории групп, но просто положено сравнение (x, y) влечет x.equals (y), если x фактически не равен y, и у меня есть карта, которая не позволяет дублировать ключи, тогда у меня есть проблема. – kag0

Смежные вопросы