Как определить путь от шумного X, Y данные

Хорошо, много вещей, чтобы упомянуть здесь ...

Для вашего первого кода, НИКОГДА НЕ ИСПОЛЬЗУЙТЕ API Contacts.People.XX, если серьезно, для чего угодно, убедитесь, что вы ничего не импортируете из People или не используете какой-либо из его API, это очень очень старый API, который был устарел много лет назад и даже не поддерживается некоторыми устройствами.

Относительно вашего второго кода, множества ошибок и проблем, которые я попытался исправить в своем коде ниже, но специально для вашего требования к производительности, обратите внимание, что вам не нужно applyBatch для каждого контакта, если вы Создайте много контактов одновременно, можно поместить множество операций в ops ArrayList и применить их все за один раз - намного быстрее!

Примечания:

  1. Это ДОЛЖНО дать вам 100-кратное увеличение для размера кэша 100, но вы можете поиграть с этим числом, просто отметьте, что, если число слишком велико, вы рискуете получить предупреждение Java «Transaction Too Large», и пакет завершится неудачей. [1111 ]
  2. Всегда снабжайте значения ACCOUNT_TYPE / ACCOUNT_NAME чем-то связанным с вашим приложением. Я добавил к этому коду два постоянных значения MY_ACCOUNT_TYPE / MY_ACCOUNT_NAME, которые вам нужно будет определить.


ArrayList<ContentProviderOperation> ops = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
    createContact(ops, name, phone);
    if (i % 100 == 0) { // experiment with different batch sizes to achieve best performance times
        try {
            contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
        } catch (RemoteException | OperationApplicationException e) {
            Log.e(TAG, "error applying batch: ", e);
        }
        ops = new ArrayList<>();
    }
}

private void createContact(ArrayList<ContentProviderOperation> ops, String name, String phone) {

    ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
            .withValue(RawContacts.ACCOUNT_TYPE, MY_ACCOUNT_TYPE)
            .withValue(RawContacts.ACCOUNT_NAME, MY_ACCOUNT_NAME).build());

    int indexOfRawContactIdOperation = ops.size() - 1;

    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, indexOfRawContactIdOperation)
            .withValue(ContactsContract.Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
            .withValue(StructuredName.DISPLAY_NAME, name)
            .build());

    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, indexOfRawContactIdOperation)
            .withValue(ContactsContract.Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
            .withValue(Phone.NUMBER, number)
            .withValue(Phone.TYPE, Phone.TYPE_MOBILE).build());
}
9
задан Frank Krueger 27 October 2008 в 16:44
поделиться

10 ответов

С неотсортированным списком Вы не будете действительно знать, какие точки включать в каждый сегмент, таким образом, я предполагаю, Вы могли просто пойти с самой близкой точкой.

Один путь мог состоять в том, чтобы выбрать стартовую точку наугад и выбрать самую близкую точку как следующий вопрос на каждом шаге. Добавьте первые две точки к набору S.

Соответствуйте строке к точкам в S, пока RMS не превышает некоторое значение, затем очистите S и запустите новую строку.

Пересечение последовательных строк было бы конечными точками сегментов.

4
ответ дан 4 December 2019 в 11:44
поделиться

Интерполяция Bezier может соответствовать Вашей проблеме.

Bezier Interpolation

Это не обращается к упорядочиванию точек в путь, однако; существует много подходов для рассмотрения:

  • Любой "оптимальный" тип пути (например, самое маленькое изменение направления в каждой точке на пути, * Кратчайший путь через все точки), вероятно, изложит NP кратко полная Проблема коммивояжера (TSP).
  • "Разумный" путь, чтобы кластеризировать узлы и затем направить между кластерами, и в кластерах. Конечно, чем больше кластер или большее количество кластеров, тем больше этой меньшей проблемы похоже на большой n TSP.
  • Упорядочивание точек одной осью. Если существует намного больше чем 2 оси, некоторая размерная стратегия сокращения может быть полезной. например, Независимый факторный анализ.
5
ответ дан 4 December 2019 в 11:44
поделиться

Если Ваши точки друг близко к другу, Вы можете нормальные "прямые" строки (ортогональные строки). Используя нормальные алгоритмы сглаживания. Вы видите мир, как являющийся плоским.

Если они далеко друг от друга, необходимо компенсировать округление земли, при помощи больших кругов для навигации от точка-точка. Иначе Ваши прямые линии сделают более длинный путь.

Это - Ваш выбор, если точка слишком далека для создания прямых линий.

Далее необходимо знать, должны ли Вы "посетить" каждую точку или просто должны пойти рядом, и как около той близости.

Если необходимо отправить курс (курсы) в плоскость, поставку или другого путешественника, вероятно, необходимо посетить каждую точку. Если Вы получаете данные GPS из объекта, Вы, вероятно, просто хотите вывести курс на печать об экране и удалить шум.


После наблюдения Ваших редактирований: Если это - объект, перемещающий некоторую переправу, Вы хотите вывестись на печать, Вы могли бы хотеть сглаживать направление и скорость вместо значений x/y. (Создание Ваших измеренных значений (x) имеет фиксированный и увеличивающийся Y-интервал, делает сглаживание намного легче.)

2
ответ дан 4 December 2019 в 11:44
поделиться

Вот эвристический взлом, который мог бы решить проблему упорядочивания для данных, если

  • у Вас есть достаточно точек
  • среднее расстояние между точками мало по сравнению с самым маленьким радиусом искривления, ожидаемого пути
  • среднее расстояние между точками не является большим по сравнению со станд. dev. шума
  • путь не самопересекается (Вы могли бы стать удачливыми, но никакие гарантии),

Продолжите двигаться как это:

  1. Выберите (надо надеяться, значимым, а не случайным средством) начальную точку, p1.
  2. Найдите все точки, которые лежат на некотором кластеризирующемся расстоянии, r_c p1. Выберите r_c маленький по сравнению с ожидаемым радиусом превращения, но большой по сравнению с рассеянием.
  3. Назовите этот кластерный C1.
  4. Найдите точку q1 средними из положений в C1.
  5. Соответствуйте строке к точкам в C1 и проекте к (или только вне) край кластера, и найдите ближайшую точку в Ваших исходных данных. Маркировка та точка p2.
  6. Выполните итерации шагов 2-5, пока у Вас не закончатся данные.

Теперь у Вас есть новый список точек q1.. qn, которые заказаны.

Первое, что пришло на ум, очень грубо, и только работает при довольно хороших условиях...


Самопересечение поведения может, вероятно, быть улучшено путем требования на шаге (5), чтобы новая спроектированная строка легла в некотором максимальном углу предыдущего.

2
ответ дан 4 December 2019 в 11:44
поделиться

Проблема с Кривой Безье, это, на самом деле не идет, хотя точки, которые Вы выбрали и даже при том, что образцы точек искажены немного; кривая Безье могла бы на самом деле быть милями прочь.

Лучшее приближение и решение, которое, кажется, напоминает исходное изображение путь лучше, являются Шлицом Catmull-Rom, потому что это действительно работает хотя все точки в кривой.

2
ответ дан 4 December 2019 в 11:44
поделиться

Мой подход должен был бы сначала отсортировать Ваш список точек, затем использовать кривую Безье.

Прием является, конечно, сортировкой. Запустите с одной случайной точки и найдите ближайшую точку. Предположите, что эти два соединены. С теми двумя конечными точками найдите ближайшие точки им. Предположите, что тот с меньшим расстоянием до он - конечная точка, подключен к той точке. Повторитесь, пока все точки не будут соединены.

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

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

1
ответ дан 4 December 2019 в 11:44
поделиться

Совершенно другой подход, который не требует другого ограничения, но деталей, может зависеть от Вашего приложения. Это sghould работают лучше всего, если у Вас есть "плотное облако точек" вокруг пути.

Используйте функцию "стоимости", которая определяет различие между кривой и облаком точек. Используйте параметрическую кривую и стандартный алгоритм оптимизации. - ИЛИ - Начинают с прямой кривой от запуска заканчиваться, затем использовать генетический алгоритм для изменения его.

Типичная функция стоимости состояла бы в том, чтобы взять наименьшее расстояние между каждой точкой и кривой, и суммировать квадраты.

У меня есть недостаточно опыта предложить оптимизацию или генетический алгоритм, но я уверен, что это может быть сделано :)

Я мог вообразить генетический алгоритм следующим образом: путь будет создан из Waypoints. Запустите с помещения N waypoints в прямой строке от запуска для окончания. (N может быть выбран в зависимости от проблемы). Мутации могли быть:

  1. Для каждого сегмента, если rnd () <x, новый waypoint представлен в середине.
  2. Для каждого waypoint X и Y координируют, варьируются немного.

Необходимо будет включать общую длину в функцию стоимости. Разделение не могло бы быть необходимо, или возможно x ("шанс разделения"), возможно, должен был бы уменьшиться, поскольку больше waypoints представлено. Вы можете или не можете хотеть подавать заявку (2) к запуску - и конечная точка.

Была бы забава попробовать это...

1
ответ дан 4 December 2019 в 11:44
поделиться

Я беру его, что "неотсортированный список" означает, что, в то время как Ваш набор точек завершен, Вы не знаете то, что приказывает, чтобы они были перемещены через?

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

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

Так, вот некоторый код Схемы PLT, который делает это.

#lang scheme

(require (only-in srfi/1 iota))

; a bunch of trig
(define (deg->rad d)
  (* pi (/ d 180)))

(define (rad->deg r)
  (* 180 (/ r pi)))

(define (euclidean-length v)
  (sqrt (apply + (map (lambda (x) (expt x 2)) v))))

(define (dot a b)
  (apply + (map * a b)))

(define (angle-ratio a b)
  (/ (dot a b)
     (* (euclidean-length a) (euclidean-length b))))

; given a list of 3 points, calculate the likelihood of the
; angle they represent. straight is better.
(define (probability-triple a b c)
  (let ([av (map - a b)]
        [bv (map - c b)])
    (cos (/ (- pi (abs (acos (angle-ratio av bv)))) 2))))

; makes a random 2d point. uncomment the bit for a 3d point
(define (random-point . x)
  (list (/ (random 1000) 100)
        (/ (random 1000) 100)
        #;(/ (random 1000) 100)))

; calculate the likelihood of an entire list of points
(define (point-order-likelihood lst)
  (if (null? (cdddr lst))
      1
      (* (probability-triple (car lst)
                             (cadr lst)
                             (caddr lst))
         (point-order-likelihood (cdr lst)))))

; just print a list of points
(define (print-points lst)
  (for ([p (in-list lst)])
    (printf "~a~n"
            (string-join (map number->string
                              (map exact->inexact p))
                         " "))))

; attempts to improve upon a list
(define (find-better-arrangement start
                                 ; by default, try only 10 times to find something better
                                 [tries 10]
                                 ; if we find an arrangement that is as good as one where
                                 ; every segment bends by 22.5 degrees (which would be
                                 ; reasonably gentle) then call it good enough. higher
                                 ; cut offs are more demanding.
                                 [cut-off (expt (cos (/ pi 8))
                                                (- (length start) 2))])
  (let ([vec (list->vector start)]
        ; evaluate what we've started with
        [eval (point-order-likelihood start)])
    (let/ec done
      ; if the current list exceeds the cut off, we're done
      (when (> eval cut-off)
        (done start))
      ; otherwise, try no more than 'tries' times...
      (for ([x (in-range tries)])
        ; pick two random points in the list
        (let ([ai (random (vector-length vec))]
              [bi (random (vector-length vec))])
          ; if they're the same...
          (when (= ai bi)
            ; increment the second by 1, wrapping around the list if necessary
            (set! bi (modulo (add1 bi) (vector-length vec))))
          ; take the values from the two positions...
          (let ([a  (vector-ref vec ai)]
                [b  (vector-ref vec bi)])
            ; swap them
            (vector-set! vec bi a)
            (vector-set! vec ai b)
            ; make a list out of the vector
            (let ([new (vector->list vec)])
              ; if it evaluates to better
              (when (> (point-order-likelihood new) eval)
                ; start over with it
                (done (find-better-arrangement new tries cut-off)))))))
      ; we fell out the bottom of the search. just give back what we started with
      start)))

; evaluate, display, and improve a list of points, five times
(define points (map random-point (iota 10)))
(define tmp points)
(printf "~a~n" (point-order-likelihood tmp))
(print-points tmp)
(set! tmp (find-better-arrangement tmp 10))
(printf "~a~n" (point-order-likelihood tmp))
(print-points tmp)
(set! tmp (find-better-arrangement tmp 100))
(printf "~a~n" (point-order-likelihood tmp))
(print-points tmp)
(set! tmp (find-better-arrangement tmp 1000))
(printf "~a~n" (point-order-likelihood tmp))
(print-points tmp)
(set! tmp (find-better-arrangement tmp 10000))
(printf "~a~n" (point-order-likelihood tmp))
(print-points tmp)
1
ответ дан 4 December 2019 в 11:44
поделиться

Кажется знанием 'золотой кривой' от ответов до вопросов я предложил бы найти Кривую Безье 'золотой кривой', как предложено @jamesh и потянуть это.

0
ответ дан 4 December 2019 в 11:44
поделиться

Сколько точек Вы имеете?
Кривая Безье, как упомянуто, является хорошей идеей, если у Вас есть comparedly немного точек. Если у Вас есть много точек, buiding кластеры, как предложено dmckee.

Однако Вам также нужно другое ограничение для определения порядка точек. Было много хороших предложений для того, как к выбрал точки, но если Вы не представляете другое ограничение, любой дает возможное решение.

Возможные ограничения я могу думать:

  • кратчайший путь
  • большинство прямых сегментов
  • наименьшее количество общего абсолютного вращения
  • направленное предпочтение (т.е. горизонтальный / вертикальный более вероятно, чем перекрещивание),

Во всех случаях для встречи ограничения, вероятно, необходимо протестировать все перестановки последовательности. Если Вы запускаете с "хорошего предположения", Вы, cayn завершают другие быстро.

0
ответ дан 4 December 2019 в 11:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: