Запрограммируйте показатель округлости

15

Ваша задача - запрограммировать математическую функцию s, которая принимает непустой конечный набор Aточек в 2D-плоскости и выводит показатель округлости, s(A)который удовлетворяет следующим свойствам:

  1. Положительная определенность : если есть круг или прямая, которая содержит все точки A, то s(A) = 0. В противном случаеs(A) > 0
  2. Сюръективность: она сюръективна с неотрицательными действительными числами, что означает, что для каждого неотрицательного действительного числа rсуществует конечное подмножество Aплоскости, такое что s(A) = r.

  3. Инвариантность перевода: s инвариантна s(A) = s(A + v)к переводу, если для каждого вектора vи для всех A.

  4. Масштабная инвариантность: s масштабно инвариантна, если s(A) = s(A * t)для всех t≠0и для всех A.

  5. Непрерывность. sназывается непрерывной, если функция f(p) := s(A ∪ {p})(отображающая точку pв действительное число) является непрерывной, используя стандартное абсолютное значение для действительных чисел и стандартную евклидову норму в точках плоскости.

Интуитивно говоря, этот показатель некруглости можно представить как нечто похожее на коэффициент корреляции в линейной регрессии.

Детали

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

flawr
источник
1
Не могли бы вы добавить несколько тестовых случаев?
Лохматый
Что значит для круга содержать все точки A ?
H.PWiz
@ H.PWiz Рассмотрим круг как подмножество 2d-плоскости, а точка содержится в круге, если она является элементом этого подмножества.
Flawr
@ Shaggy Нет, это невозможно, так sкак не является уникальным. Единственное, к чему вы могли бы привести примеры, - s(A) = 0это тривиально, используя первое свойство.
Flawr
Может ли наша программа выдать ошибку теоретически с нулевой вероятностью? (фактическая вероятность отлична от нуля, потому что число с плавающей запятой дискретно) / Вы допускаете игнорирование неточностей с плавающей запятой? Соответствующая мета .
user202729

Ответы:

2

Python 2 с NumPy, 116 байт

from numpy import*
def f(x,y):a=linalg.lstsq(hstack((x,y,ones_like(x))),(x*x+y*y)/2);return a[1]/sum((x-a[0][0])**4)

Принимает x и y в качестве двухмерных векторов столбцов и возвращает массив, содержащий ответ. Обратите внимание, что это даст пустой массив для идеально прямой линии или с 3 или менее точками. Я думаю, что lstsq не дает остатков, если есть идеальное соответствие.

объяснение

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

Мы хотим минимизировать (x - x_center)^2 + (y - y_center)^2 - R^2. Это выглядит противным и нелинейными, но мы можем переписать , что , как x_center(-2x) + y_center(-2y) + stuff = x^2 + y^2, где stuffдо сих пор противно и нелинейно с точки зрения x_center, y_centerи R, но мы не должны заботиться о нем. Так что мы можем просто решить [-2x -2y 1][x_center, y_center, stuff]^T = [x^2 + y^2].

Мы могли бы тогда отказаться от R, если бы мы действительно хотели, но это не сильно нам помогает здесь. К счастью, функция lstsq может дать нам невязки, которые удовлетворяют большинству условий. Вычитание центра и масштабирование (R^2)^2 = R^4 ~ x^4дает нам поступательную и масштабную инвариантность.

  1. Это определенно положительно, потому что квадратичные остатки неотрицательны, и мы делим на квадрат. Он стремится к 0 для кругов и линий, потому что мы подгоняем круг.
  2. Я вполне уверен, что это не сюръективно, но я не могу получить хорошую оценку. Если есть верхняя граница, мы можем отобразить [0, bound) с неотрицательными вещественными значениями (например, с 1 / (bound-answer) - 1 / bound) для еще нескольких байтов.
  3. Мы вычитаем центр, так что он трансляционно инвариантен.
  4. Делим на х ** 4, что снимает зависимость от масштаба.
  5. Он состоит из непрерывных функций, поэтому он непрерывен.

источник
Можете ли вы описать, что на самом деле делает ваше подразделение?
flawr
@flawr Отредактировал это в.
Я пытался проверить это на {(1, 0), (2, 0), (3, 0), (4, t)} при t → 0, но, f(array([[1.0],[2.0],[3.0],[4.0]]),array([[0.0],[0.0],[0.0],[t]]))похоже, дает мне array([ 0.00925926])все ненулевые значения t. (Я знаю, что вы сказали, что это разрывы при t = 0, но результат должен как минимум приблизиться к 0 при t → 0.) Я неправильно это называю?
Андерс Касорг
2

Python, 124 байта

lambda A:sum(r.imag**2/2**abs(r)for a in A for b in A for c in A for d in A if a!=d!=b!=c for r in[(a-c)*(b-d)/(a-d)/(b-c)])

Принимает А как последовательность комплексных чисел ( x + 1j*y), и суммирует Im ( г ) 2 /2 | г | для всех сложных перекрестных соотношений г из четырех точек А , .

свойства

  1. Положительная определенность. Все слагаемые неотрицательны, и все они равны нулю именно тогда, когда все перекрестные отношения являются действительными, что происходит, когда точки коллинеарны или являются циклическими.

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

  3. Инвариантность перевода. Соотношение является трансляционно-инвариантным.

  4. Шкала инвариантности. Соотношение является масштабно-инвариантным. (На самом деле, он инвариантен относительно всех преобразований Мёбиуса.)

  5. Непрерывность. Двойное отношение является непрерывное отображение на расширенной комплексной плоскости, а г ↦ Im ( г ) 2 /2 | г | (с ∞ ↦ 0) - непрерывное отображение от расширенной комплексной плоскости до вещественных чисел.

(Примечание: теоретически более симпатичная карта с теми же свойствами имеет вид r ↦ (Im ( r ) / ( C + | r | 2 )) 2 , контурные линии которого по всем четырем точкам перекрестного отношения являются круглыми. Если вам действительно нужно мера округлости, вы, вероятно, хотите это.)

Андерс Касеорг
источник