хорошо, я просто сделал что-то подобное, но не идентичный, таким образом, я запишу контрольный список вещей для Вас проверить. Я следовал инструкциям в страница справки человечности
, у меня была следующая установка в acl блоке (другой IP).
acl home src 50.50.50.50
Кроме того, согласно шагу 3, я также добавил следующее в
http_access allow home
Рассмотрение, что Вы вошли 127.0.0.1, существует несколько вещей проверить. Здесь 127.0.0.1 средства, сквид только позволяет с самого сервера EC2, таким образом, скорее всего, необходимо использовать lync или другой такой инструмент для отправления запросов от ec2. Я предполагаю, что Вы тестируете от своего домашнего компьютера, и это не 127.0.0.1. Необходимо узнать общедоступный IP-адрес и ввести его в конфигурацию.
Кроме того, Вы указали/32 в своем IP. Проверьте, что это необходимо. Для общедоступных IP-адресов это не. Это требовалось бы в настройке сети, но вероятно не нужное в Вашем сценарии.
я смог получить его работа, надо надеяться, Вы будете также.
Большинство древовидных структур данных используют какой-то алгоритм сортировки для хранения и поиска ключей. Многие реализации такого рода могут определять местонахождение ключа, близкого к ключу, которым вы исследуете (обычно это либо ближайший ниже, либо самый близкий вверху). Например, Java TreeMap
реализует такую структуру данных, и вы можете указать ему, чтобы он предоставил вам ближайший ключ под ключом поиска или ближайший ключ над ключом поиска ( upperKey
и ] lowerKey
).
Если вы можете рассчитать расстояния (это не всегда просто - интерфейс Java требует, чтобы вы знали, находится ли любой заданный ключ «ниже» или «выше» любого другого заданного ключа), тогда вы можете запросить как ближайшие вверху, так и внизу, а затем вычислите для себя, какой из них ближе.
Какова размерность ваших данных? Если он всего лишь одномерный, то это сделает отсортированный массив - двоичный поиск найдет точное совпадение и / или покажет, между какими двумя ключами лежит ваш ключ поиска - и простой тест покажет вам, какой из них ближе.
Если вы нужно найти не только ближайший ключ, но и соответствующее значение,
Вы можете реализовать что-то подобное в виде дерева. Простой подход - назначить каждому узлу в дереве цепочку битов. Каждый уровень дерева хранится в виде бита. Вся родительская информация закодирована в цепочке битов узла. Затем вы можете легко найти произвольные узлы и найти родителей и детей. Так работает, например, порядок Мортона . У него есть дополнительное преимущество, заключающееся в том, что вы можете вычислять расстояния между узлами с помощью простого двоичного вычитания.
Если у вас есть несколько связей между значениями данных, ваша структура данных представляет собой график, а не дерево. В этом случае вам понадобится немного более сложная система индексации. Распределенные хеш-таблицы делают такие вещи. Обычно у них есть способ вычисления расстояния между любыми двумя узлами в индексном пространстве. Например, алгоритм Kademlia (используемый Bittorrent) использует расстояния XOR, применяемые к идентификаторам битовых строк. Это позволяет клиентам Bittorrent искать идентификаторы в цепочке, сходящейся в неизвестном целевом местоположении. Вы можете использовать аналогичный подход для поиска узлов, ближайших к вашему целевому узлу.
Если ваши ключи являются строками, а ваша функция сходства - расстояние Левенштейна , то вы можете использовать конечные автоматы :
Ваша карта дерево , построенное как конечный автомат (путем объединения всех пар ключ / значение и определения). Затем составьте входной запрос с помощью простого преобразователя с конечным числом состояний, который кодирует расстояние Левенштейна, и скомпонуйте его с помощью своего дерева. Затем используйте алгоритм Витерби , чтобы извлечь кратчайший путь.
Вы можете реализовать все это с помощью всего лишь нескольких вызовов функций, используя набор инструментов с конечным числом состояний .
BK-деревья делают именно то, что вы хотите. Вот хорошая статья об их реализации.
А вот реализация на Scala:
class BKTree[T](computeDistance: (T, T) => Int, node: T) {
val subnodes = scala.collection.mutable.HashMap.empty[Int,BKTree[T]]
def query(what: T, distance: Int): List[T] = {
val currentDistance = computeDistance(node, what)
val minDistance = currentDistance - distance
val maxDistance = currentDistance + distance
val elegibleNodes = (
subnodes.keys.toList
filter (key => minDistance to maxDistance contains key)
map subnodes
)
val partialResult = elegibleNodes flatMap (_.query(what, distance))
if (currentDistance <= distance) node :: partialResult else partialResult
}
def insert(what: T): Boolean = if (node == what) false else (
subnodes.get(computeDistance(node, what))
map (_.insert(what))
getOrElse {
subnodes(computeDistance(node, what)) = new BKTree(computeDistance, what)
true
}
)
override def toString = node.toString+"("+subnodes.toString+")"
}
object Test {
def main(args: Array[String]) {
val root = new BKTree(distance, 'A')
root.insert('C')
root.insert('M')
root.insert('Z')
println(findClosest(root, 'D'))
}
def charDistance(a: Char, b: Char) = a - b abs
def findClosest[T](root: BKTree[T], what: T): List[T] = {
var distance = 0
var closest = root.query(what, distance)
while(closest.isEmpty) {
distance += 1
closest = root.query(what, distance)
}
closest
}
}
Я признаю некоторую грязь и некрасивость в этом, а также слишком умен в алгоритме вставки. Кроме того, он будет работать только на небольшом расстоянии, иначе вы будете постоянно искать дерево. Вот альтернативная реализация, которая лучше справляется с этой задачей:
class BKTree[T](computeDistance: (T, T) => Int, node: T) {
val subnodes = scala.collection.mutable.HashMap.empty[Int,BKTree[T]]
def query(what: T, distance: Int): List[T] = {
val currentDistance = computeDistance(node, what)
val minDistance = currentDistance - distance
val maxDistance = currentDistance + distance
val elegibleNodes = (
subnodes.keys.toList
filter (key => minDistance to maxDistance contains key)
map subnodes
)
val partialResult = elegibleNodes flatMap (_.query(what, distance))
if (currentDistance <= distance) node :: partialResult else partialResult
}
private def find(what: T, bestDistance: Int): (Int,List[T]) = {
val currentDistance = computeDistance(node, what)
val presentSolution = if (currentDistance <= bestDistance) List(node) else Nil
val best = currentDistance min bestDistance
subnodes.keys.foldLeft((best, presentSolution))(
(acc, key) => {
val (currentBest, currentSolution) = acc
val (possibleBest, possibleSolution) =
if (key <= currentDistance + currentBest)
subnodes(key).find(what, currentBest)
else
(0, Nil)
(possibleBest, possibleSolution) match {
case (_, Nil) => acc
case (better, solution) if better < currentBest => (better, solution)
case (_, solution) => (currentBest, currentSolution ::: solution)
}
}
)
}
def findClosest(what: T): List[T] = find(what, computeDistance(node, what))._2
def insert(what: T): Boolean = if (node == what) false else (
subnodes.get(computeDistance(node, what))
map (_.insert(what))
getOrElse {
subnodes(computeDistance(node, what)) = new BKTree(computeDistance, what)
true
}
)
override def toString = node.toString+"("+subnodes.toString+")"
}
object Test {
def main(args: Array[String]) {
val root = new BKTree(distance, 'A')
root.insert('C')
root.insert('E')
root.insert('M')
root.insert('Z')
println(root.findClosest('D'))
}
def charDistance(a: Char, b: Char) = a - b abs
}