- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个包含商店 ID、纬度和经度的列表。假设我们的点数是偶数,我想将每家商店与另一家商店相匹配,这样我们的连接是唯一的,并且我们可以最小化总距离。
我很好奇我的方法是不是太愚蠢了,还有更好的方法。目前,这可以在合理的时间内(一小时)为 1000 点工作。
假设我们有一个这样的列表:
shops = [[1, '53.382072', '-2.7262165'],
[2, '52.478499', '-0.9222608'],
[3, '52.071258', '-1.2722802'],
...]
并且我使用 PuLP 使用此工作流程创建 .lp 文件:
prob = LpProblem("Minimise distance",LpMinimize)
# Variables
x = []
xnames = []
for one in store_connect(shops):
xnames.append(one)
x.append(LpVariable(one,0,1,LpInteger))
print("Created %d variables" % len(x))
# Objective
prob += pulp.lpSum([i[1]*x[i[0]] for i in enumerate(distances(shops))])
print("Created objective")
# Constraints
counter = 0
for constraint_rw in all_constraints(shops):
prob += pulp.lpSum(x[xnames.index(one_cn)] for one_cn in constraint_rw) == 1
counter += 1
if counter % 10 == 0:
print("Added %d contraints out of %d" % (counter,len(shops)))
# Save "LP" file for other solvers
prob.writeLP("for_cplex.lp")
我在哪里调用了一些生成器函数(以帮助 RAM ...)
def store_connect(shops):
"""
Cross stores and return connection e.g. "v1-2" by ID
"""
for i in range(len(shops)-1):
for j in range(i+1,len(shops)):
yield 'v'+str(shops[i][0])+'-'+str(shops[j][0])
def distances(shops):
"""
Return distance in miles for crosses
"""
for i in range(len(shops)-1):
for j in range(i+1,len(shops)):
yield haversine([shops[i][1],shops[i][2]],
[shops[j][1],shops[j][2]])
def all_constraints(shops):
"""
Return constraint row
"""
for a in shops:
cons = []
for b in shops:
if a[0]<b[0]:
cons.append("v"+str(a[0])+"-"+str(b[0]))
elif a[0]>b[0]:
cons.append("v"+str(b[0])+"-"+str(a[0]))
yield cons
如果我在 100 家商店上运行它,速度会非常快,而且我可以使用默认的 PuLP 求解器。否则,我将 LP 文件提交到 NEOS 服务器上的 CPLEX。我创建了一个小的辅助函数来可视化结果匹配:
以下是我的 LP 文件如何查找 10 家商店的简单示例(已截断):
Minimize
OBJ: 131.513 v1_10 + 97.686 v1_2 + 109.107 v1_3 + 36.603 v1_4 + 11.586 v1_5
+ 109.067 v1_6 + 113.862 v1_7 + 169.371 v1_8 + 220.098 v1_9 + 101.958 v2_10
+ 31.793 v2_3 + 61.792 v2_4 + 105.822 v2_5 + 73.055 v2_6 + 32.008 v2_7
+ 81.627 v2_8 + 122.493 v2_9 + 72.945 v3_10 + 72.983 v3_4 + 114.609 v3_5
+ 46.098 v3_6 + 5.555 v3_7 + 60.305 v3_8 ...
Subject To
_C1: v1_10 + v1_2 + v1_3 + v1_4 + v1_5 + v1_6 + v1_7 + v1_8 + v1_9 = 1
_C10: v1_10 + v2_10 + v3_10 + v4_10 + v5_10 + v6_10 + v7_10 + v8_10 + v9_10
= 1
_C2: v1_2 + v2_10 + v2_3 + v2_4 + v2_5 + v2_6 + v2_7 + v2_8 + v2_9 = 1
_C3: v1_3 + v2_3 + v3_10 + v3_4 + v3_5 + v3_6 + v3_7 + v3_8 + v3_9 = 1
_C4: v1_4 + v2_4 + v3_4 + v4_10 + v4_5 + v4_6 + v4_7 + v4_8 + v4_9 = 1
_C5: v1_5 + v2_5 + v3_5 + v4_5 + v5_10 + v5_6 + v5_7 + v5_8 + v5_9 = 1
...
Binaries
v1_10
v...
End
结果:
Status: Optimal
Total minimised distance (miles): 190.575
最后,这是一个关于 1000 点的更大的例子:
最佳答案
考虑一个 pandas解决方案(Python 的数据分析包)。我的初等几何提醒我,两点之间最近的距离是一条直线,它在坐标平面中是 Lat 和 Lng 点之间的斜边。
下面首先运行商店之间的笛卡尔乘积(集合之间所有可能的组合),然后使用地理坐标计算斜边。从那里聚合最小值:
import pandas as pd
# ORIGINAL LIST
shops = [[1, 53.382072, -2.7262165],
[2, 52.478499, -0.9222608],
[3, 52.071258, -1.2722802]]
# CONVERTING INTO TWO DUPLICATE SHOPS DATA FRAMES
shopsdfA = pd.DataFrame(shops, columns=['ID_A', 'Lat_A', 'Lng_A'])
shopsdfA['key']=1
shopsdfB = pd.DataFrame(shops, columns=['ID_B', 'Lat_B', 'Lng_B'])
shopsdfB['key']=1
# CROSS JOINING BOTH DATA FRAMES FOR CARTESIAN PRODUCT SET
compareshops = pd.merge(shopsdfA, shopsdfB, on='key')[['ID_A', 'Lat_A', 'Lng_A',
'ID_B','Lat_B', 'Lng_B']]
# (REMOVING SHOPS COMPARED TO ITSELF)
compareshops = compareshops[compareshops['ID_A'] != compareshops['ID_B']].\
reset_index(drop=True)
# ID_A Lat_A Lng_A ID_B Lat_B Lng_B
#0 1 53.382072 -2.726217 2 52.478499 -0.922261
#1 1 53.382072 -2.726217 3 52.071258 -1.272280
#2 2 52.478499 -0.922261 1 53.382072 -2.726217
#3 2 52.478499 -0.922261 3 52.071258 -1.272280
#4 3 52.071258 -1.272280 1 53.382072 -2.726217
#5 3 52.071258 -1.272280 2 52.478499 -0.922261
# CALCULATE HYPOTENUSE
compareshops['hypotenuse'] = ((compareshops['Lat_A'] - compareshops['Lat_B']) ** 2 +
(compareshops['Lng_A'] - compareshops['Lng_B']) ** 2) ** (1/2)
# ID_A Lat_A Lng_A ID_B Lat_B Lng_B hypotenuse
#0 1 53.382072 -2.726217 2 52.478499 -0.922261 2.017598
#1 1 53.382072 -2.726217 3 52.071258 -1.272280 1.957591
#2 2 52.478499 -0.922261 1 53.382072 -2.726217 2.017598
#3 2 52.478499 -0.922261 3 52.071258 -1.272280 0.536991
#4 3 52.071258 -1.272280 1 53.382072 -2.726217 1.957591
#5 3 52.071258 -1.272280 2 52.478499 -0.922261 0.536991
# AGGREGATE FOR MINIMUM HYPOTENUSE AND MERGE CORRESPONDING PAIRED IDS
compareshops = pd.merge(compareshops[['ID_A','hypotenuse']].groupby(['ID_A']).min().reset_index(),
compareshops[['ID_B','hypotenuse']], on='hypotenuse')
# (REMOVING SAME STORE PAIRINGS)
compareshops = compareshops[compareshops['ID_A'] != compareshops['ID_B']].\
reset_index(drop=True)[['ID_A','ID_B','hypotenuse']]
# ID_A ID_B hypotenuse
#0 1 3 1.957591
#1 2 3 0.536991
#2 3 2 0.536991
一个可预见的挑战是您的 map 没有重叠连接,每个商店只有一对。可能需要运行迭代斜边计算以找到“下一个”最短距离。
关于python - 将许多点分组为最接近的对 - Python + LP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35162601/
我想创建一个返回值的方法(我们称之为“z”)。它的值由另一个值决定(我们称之为“y”)。基本上我想要的是满足以下条件: 当 x 接近 0 时,z 接近 100。 当 x 接近无穷大时,z 接近 0。
我正在尝试使用 Java 中的PreparedStatement 执行查询。 当我尝试执行查询时,收到错误号 1064(语法错误)。 我已经在 MySQL 查询浏览器中使用替换值对此进行了测试,效果很
我正在开发一个应用程序来解析 Scala 中的命令。命令的一个例子是: todo get milk for friday 所以计划是让一个非常智能的解析器将行分开并识别命令部分以及字符串中有时间引用的
来自 http://directwebremoting.org/dwr/reverse-ajax/index.html ,它表示它支持轮询、 cometd 、搭载。这是否意味着当我们实现这种方法时,我
我开始研究一个概念,该概念要求我找到一种方法,以给定的速度将矩形移向给定的点。我正在为 Android 开发,所以这对速度非常关键(它也将针对可能的数百个对象计算每一帧。) 我能想到的解决方案如下:
我正在处理一个处理“门票”的表(状态=“开放”或状态=“关闭”)。当票证关闭时,相关系统不会更改状态,而是会创建一个具有“已关闭”状态的重复条目。 对于“ticket_number”关键字段,如果存在
我正在尝试在 python 中执行一些 n-gram 计数,我想我可以使用 MySQL(MySQLdb 模块)来组织我的文本数据。 我有一个很大的表,大约有 1000 万条记录,代表由唯一数字 ID(
我正在尝试将数据添加到 mariadb 表中。我想将 val0 到 val5 作为查询的值传递。但我收到错误 OperationalError: close "%": 语法错误代码 list_Valu
我正在使用 (Py)OpenGL 显示 256 色索引图像。我将着色器与包含调色板的一维纹理一起使用。这是片段着色器代码: #version 330 uniform sampler2D texture
对于我的元素 areallybigpage.com (*),我想看看我们能用 CSS 的 transform: scale(...) 走多远。 这有效并以正常大小显示文本: #id1 { positi
我有两列带有数字数据的 Pandas 表(dtype flaot64)。 我将每列四舍五入到小数点后有 2 位数字,然后使用函数将其四舍五入到接近 0.5,但由于某种原因,只有一列四舍五入为 0.05
我正在构建一个由用户登录和注册组成的应用程序,但每次我在模拟器上测试它时,我都会收到强制关闭。以下是我在日志猫中收到的错误: 08-14 14:06:28.853: D/dalvikvm(828):
我正在尝试在 Python 中实现 Strassen 矩阵乘法。我已经让它发挥了一些作用。这是我的代码: a = [[1,1,1,1],[2,2,2,2],[3,3,3,3],[4,4,4,4]] b
为什么这不起作用?这与 = 附近的命令字符串语法有关,但我似乎无法弄清楚,在线示例似乎完全相同。编辑: Activated In 是一列。 示例来自 How to select data from d
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求提供代码的问题必须表现出对所解决问题的最低限度理解。包括尝试过的解决方案、为什么它们不起作用,以及
我有一个测试区,它是来自数据库的动态文本,可能有数千个单词。我希望它中断并在每段中用句号将近 100 个(任意长度)单词作为一个段落。我能够在 100 个单词后中断,但不能完全停止。为了在 100 个
我是 hadoop 和 hive 的新手。我正在尝试将数据加载到配置单元表中,但遇到以下错误。 另一方面,我尝试使用语句 stmt.execute("INSERT INTO employee VALU
这是来自一个统计项目。我定义了下面的函数,但是当n接近400时,第二个方法很慢。第一个方法很好(这里有人帮助了我in this question) import Math.Combinatorics.
我正在尝试创建一个 css 侧边菜单,但是当我关闭菜单并将 div 容器宽度设置为 0 时,链接仍然可见。 这是 jsfiddle - https://jsfiddle.net/atLvp6k7/ 有
我对 MySQL 还很陌生。我必须使用输出参数调用存储过程。我在互联网上搜索了很多,但没有找到解决我的问题的正确方法。如果我使用 @outputParamName 调用存储过程,它会说我在 NULL
我是一名优秀的程序员,十分优秀!