- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
假设给定了 3 个维度中包含 n 个点的集合 S。任意两点之间的距离是简单的欧氏距离。你想从这个集合中选择 k 个点的子集 Q,使它们彼此相距最远。换句话说,不存在其他 k 个点的子集 Q',使得 Q 中所有成对距离的最小值小于 Q' 中的最小值。
如果 n 约为 1600 万,k 约为 300,我们如何有效地做到这一点?
我的猜测是,这个 NP-hard 问题可能是因为我们只想关注近似值。我能想到的一个想法是使用多维缩放将这些点排成一条直线,然后使用二进制搜索的版本来获取这条线上相距最远的点。
最佳答案
这被称为离散 p 色散 (maxmin) 问题。
最优界在 White (1991) 中得到证明和 Ravi et al. (1994)给出问题的因子 2 近似值,后者证明这种启发式是最好的(除非 P=NP)。
factor-2 近似如下:
Let V be the set of nodes/objects.
Let i and j be two nodes at maximum distance.
Let p be the number of objects to choose.
P = set([i,j])
while size(P)<p:
Find a node v in V-P such that min_{v' in P} dist(v,v') is maximum.
\That is: find the node with the greatest minimum distance to the set P.
P = P.union(v)
Output P
您可以像这样在 Python 中实现它:
#!/usr/bin/env python3
import numpy as np
p = 50
N = 400
print("Building distance matrix...")
d = np.random.rand(N,N) #Random matrix
d = (d + d.T)/2 #Make the matrix symmetric
print("Finding initial edge...")
maxdist = 0
bestpair = ()
for i in range(N):
for j in range(i+1,N):
if d[i,j]>maxdist:
maxdist = d[i,j]
bestpair = (i,j)
P = set()
P.add(bestpair[0])
P.add(bestpair[1])
print("Finding optimal set...")
while len(P)<p:
print("P size = {0}".format(len(P)))
maxdist = 0
vbest = None
for v in range(N):
if v in P:
continue
for vprime in P:
if d[v,vprime]>maxdist:
maxdist = d[v,vprime]
vbest = v
P.add(vbest)
print(P)
您也可以将其建模为 MIP。对于 p=50,n=400 6000 秒后,最优性差距仍为 568%。近似算法用了 0.47s 来获得 100%(或更少)的最优性差距。朴素的 Gurobi Python 表示可能如下所示:
#!/usr/bin/env python
import numpy as np
import gurobipy as grb
p = 50
N = 400
print("Building distance matrix...")
d = np.random.rand(N,N) #Random matrix
d = (d + d.T)/2 #Make the matrix symmetric
m = grb.Model(name="MIP Model")
used = [m.addVar(vtype=grb.GRB.BINARY) for i in range(N)]
objective = grb.quicksum( d[i,j]*used[i]*used[j] for i in range(0,N) for j in range(i+1,N) )
m.addConstr(
lhs=grb.quicksum(used),
sense=grb.GRB.EQUAL,
rhs=p
)
# for maximization
m.ModelSense = grb.GRB.MAXIMIZE
m.setObjective(objective)
# m.Params.TimeLimit = 3*60
# solving with Glpk
ret = m.optimize()
显然,初始点的 O(N^2) 缩放很糟糕。通过认识到这对必须位于数据集的凸包上,我们可以更有效地找到它们。这为我们提供了一种O(N log N) 的方法来找到这对。一旦我们找到它,我们就会像以前一样进行(使用 SciPy 进行加速)。
缩放的最佳方法是使用 R* 树有效地找到候选点 p 和集合 P 之间的最小距离。但这在 Python 中不能有效地完成,因为 for
循环仍然存在。
import numpy as np
from scipy.spatial import ConvexHull
from scipy.spatial.distance import cdist
p = 300
N = 16000000
# Find a convex hull in O(N log N)
points = np.random.rand(N, 3) # N random points in 3-D
# Returned 420 points in testing
hull = ConvexHull(points)
# Extract the points forming the hull
hullpoints = points[hull.vertices,:]
# Naive way of finding the best pair in O(H^2) time if H is number of points on
# hull
hdist = cdist(hullpoints, hullpoints, metric='euclidean')
# Get the farthest apart points
bestpair = np.unravel_index(hdist.argmax(), hdist.shape)
P = np.array([hullpoints[bestpair[0]],hullpoints[bestpair[1]]])
# Now we have a problem
print("Finding optimal set...")
while len(P)<p:
print("P size = {0}".format(len(P)))
distance_to_P = cdist(points, P)
minimum_to_each_of_P = np.min(distance_to_P, axis=1)
best_new_point_idx = np.argmax(minimum_to_each_of_P)
best_new_point = np.expand_dims(points[best_new_point_idx,:],0)
P = np.append(P,best_new_point,axis=0)
print(P)
关于python - 在给定的点集中选择最远点的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48925086/
我想做一个系统,用户可以上传和下载文件。系统将具有一个集中的地形,但在很大程度上依赖于节点将相关数据通过中心节点传输给其他节点我不希望对等端保存整个文件,而是希望它们保存整个数据集的一个压缩的加密部分
我正在 Riverpod Auth 流程样板应用程序中工作。 我想对所有异步功能甚至登录和注销使用通用加载屏幕。目前,如果 Appstate 加载我显示加载屏幕,我有 AppState 提供程序。它可
我有一个 functions.php 文件,其中包括以下功能: function head() { global $brand, $brandName, $logo, $slogan, $si
我有下一个 html 代码 ... 我想选择随机的 div 数组来向它们添加一个事件类,因为我使用这个 jquery 代码 function randOrder() { return
多年来,我创建并调整了一组NAnt脚本以执行完整的项目构建。主脚本采用一个应用程序端点(例如,一个Web应用程序项目),并从源代码控制中对其进行完整的构建。脚本已预先配置了与构建输出位置,源代码控制地
我希望我的 jQuery 插件在 $(window) 选择上调用时表现不同。如何检查 window 是否在集合中?到目前为止我的尝试: >>> $(window) == $(window) false
考虑到我们有 let existingSet = $(); 如何通过 jQuery 将 newElements 添加到该集合中? existingSet = existingSet.add(newEl
我需要在 priority_queue 中保存一个整数集合。但是我需要能够删除这些整数中的一个,即使它不是我容器的第一个元素。我无法使用 std::priority_queue。我选择使用一个集合来根
对于我的网站,我一直在尝试集中所有内容以便在移动设备上显示: http://m.bachatdeals.com 我在移动设备上打开网站后,内容下方有很多空间,我必须捏住 zoon 才能阅读,如何删除下
我计划为我的剑道验证器制定一些自定义规则,并希望在所有验证器之间共享。在我的验证器代码中,我有: rules: { bothorblank: function (input) {
这是我的函数,用于测试两个点 x 和 y 在 MAX_ITERATION 255 之后是否在 mandelbrot 集合中。如果不在,它应该返回 0,如果在,则返回 1。 int isMandelbr
致力于从移动设备扩展到桌面设备的简单网站布局。一切都按预期工作,但由于某种原因,我的 float div 没有集中放置。我已经完成了正常工作,但这次不适合我?有什么想法吗? 这是我的 CSS: /*
我的“div”元素有一个相对宽度,它不是绝对的,所以我不能使用精确的数字来集中。一个不错的解决方案是使用“display: inline-block”: body { text-align:
目前我拥有的所有类都处理它们自己的导入。使用一个典型的例子: [ImportMany] private Lazy[] someOfMyInterfaces { get; set; } public M
我有一个类定义: class Question: title = "" answer = "" def __init__(self, title, answer):
我正在尝试将一个对象 Point2D 插入到一个 Point2D 集合中,但我做不到,似乎该集合适用于 int 和 char 但不适用于对象。 我需要帮助来了解如何将对象插入到集合中???假设我想按
我的应用上有一些弹出窗口,它是全屏的,代码如下: content.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
我们有一个多模块 Quarkus 项目,带有一个公共(public)库和多个应用程序。在通用的 lib 中,我们有各种缓存用于所有应用。 我们希望不必在每个应用程序的所有配置文件中配置保留和容量。 有
这个问题在这里已经有了答案: Nested facets in ggplot2 spanning groups (2 个回答) 去年关闭。 我在 ggplot 中创建了一个图表里面有两个变量 face
我无法集中v-radio-group。这是我得到的:
我是一名优秀的程序员,十分优秀!