- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个类型 A 的有序项目列表,每个项目包含项目 B 列表的一个子集。对于 A 中的每对项目,我想找到它们共享(相交)的项目 B 的数量.
例如,如果我有这个数据:
A1 : B1
A2 : B1 B2 B3
A3 : B1
然后我会得到以下结果:
A1, A2 : 1
A1, A3 : 1
A2, A3 : 1
我遇到的问题是使算法高效。我的数据集的大小约为 8.4K 项类型 A。这意味着 8.4K 选择 2 = 35275800 组合。我使用的算法只是遍历每个组合对并进行集合交集。
到目前为止,我所拥有的要点如下。我将计数作为键存储在映射中,值作为 A 对的 vector 。我正在使用图形数据结构来存储数据,但我使用的唯一“图形”操作是 get_neighbors() ,它返回 A 中某项的 B 子集。我碰巧知道图形中的元素是从索引 0 到 8.4K 排序。
void get_overlap(Graph& g, map<int, vector<A_pair> >& overlap) {
map<int, vector<A_pair> >::iterator it;
EdgeList el_i, el_j;
set<int> intersect;
size_t i, j;
VertexList vl = g.vertices();
for (i = 0; i < vl.size()-1; i++) {
el_i = g.get_neighbors(i);
for (j = i+1; j < vl.size(); j++) {
el_j = g.get_neighbors(j);
set_intersection(el_i.begin(), el_i.end(), el_j.begin(), el_j.end(), inserter(intersect, intersect.begin()));
int num_overlap = intersect.size();
it = overlap.find(num_overlap);
if (it == overlap.end()) {
vector<A_pair> temp;
temp.push_back(A_pair(i, j));
overlap.insert(pair<int, vector<A_pair> >(num_overlap, temp));
}
else {
vector<A_pair> temp = it->second;
temp.push_back(A_pair(i, j));
overlap[num_overlap] = temp;
}
}
}
}
我已经运行这个程序将近 24 小时了,for 循环中的第 i 个元素已经达到迭代 250(我正在将每个 i 打印到一个日志文件中)。当然,这与 8.4K 相去甚远(尽管我知道随着迭代的进行,比较次数会缩短,因为 j = i +1)。有没有更优化的方法?
编辑:明确地说,这里的目标最终是找到前 k 个重叠对。
编辑 2:感谢@Beta 和其他人指出优化。特别是,直接更新 map (而不是复制其内容并重置 map 值)极大地提高了性能。它现在可以在几秒钟内运行。
最佳答案
我认为您可以通过预先计算反向(边到顶点)映射来加快速度。这将允许您避免 set_intersection 调用,它执行一堆昂贵的集合插入。我缺少一些声明来制作功能齐全的代码,但希望你能明白。我假设 EdgeList 是某种 int vector :
void get_overlap(Graph& g, map<int, vector<A_pair> >& overlap) {
map<int, vector<A_pair> >::iterator it;
EdgeList el_i, el_j;
set<int> intersect;
size_t i, j;
VertexList vl = g.vertices();
// compute reverse map
map<int, set<int>> reverseMap;
for (i = 0; i < vl.size()-1; i++) {
el_i = g.get_neighbors(i);
for (auto e : el_i) {
const auto findIt = reverseMap.find(e);
if (end(reverseMap) == findIt) {
reverseMap.emplace(e, set<int>({i})));
} else {
findIt->second.insert(i);
}
}
}
for (i = 0; i < vl.size()-1; i++) {
el_i = g.get_neighbors(i);
for (j = i+1; j < vl.size(); j++) {
el_j = g.get_neighbors(j);
int num_overlap = 0;
for (auto e: el_i) {
auto findIt = reverseMap.find(e);
if (end(reverseMap) != findIt) {
if (findIt->second.count(j) > 0) {
++num_overlap;
}
}
}
it = overlap.find(num_overlap);
if (it == overlap.end()) {
overlap.emplace(num_overlap, vector<A_pair>({ A_pair(i, j) }));
}
else {
it->second.push_back(A_pair(i,j));
}
}
}
我没有做精确的性能分析,但在双循环中,你用 N*log(M)*log(E) 比较替换“最多 4N 次比较”+ 一些昂贵的集合插入(来自 set_intersection),其中 N 是每个顶点的平均边数,M 是每个边的平均顶点数,E 是边数,因此根据您的数据集,它可能是有益的。此外,如果您的边缘索引很紧凑,那么您可以使用简单 vector 而不是 map 来表示反向 map ,这消除了 log(E) 性能成本。
不过有一个问题。既然你在谈论顶点和边,难道你没有边总是有 2 个顶点的额外约束吗?这可以简化一些计算。
关于c++ - 在组合对之间找到共享元素的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21735196/
只是想知道是否有可能找出谁从 Windows 共享中读取了文件(最好使用 .NET,但 win32 native 可以)? 我想做的是创建类似 awstats 的东西对于 Windows 共享,这样我
是否可以列出 Intent.ACTION_SEND ?我的意思是我需要知道是否有人通过 action_send 在 Facebook 上分享或在 Twitter 上发推文。 最佳答案 也许你想要一个更
我正在使用 Google Apps 应用程序。实际上,我想在不使用密码的情况下访问另一个 ID。我使用了 OAuth,它运行良好。但我无法分享特定人的日历。我尝试了以下代码。 GoogleOAuthP
我怎样才能只创建模拟器...可能吗?我知道,设备需要分发证书。 最佳答案 您只需将应用程序目录从 iPhone 模拟器复制到另一个实例/操作系统版本,它就应该可以工作。 因此,如果您想分发 3.1.3
我想使用多阶段构建来避免每次构建应用程序时都下载我的 Java 项目所需的所有 Maven 依赖项。 我正在考虑在第一阶段解决 Maven 依赖项,然后在第二阶段构建应用程序,这将需要访问在前一阶段下
我正在寻找保护用户下载内容的初步想法。用户下载充满有趣资源的 zip 文件,这些资源被提取到本地文件系统中以供应用程序使用。我的目标是防止用户通过互联网将下载的资源共享给其他用户(假设他们获得了对文件
我想知道在具有移动和桌面版本的网站上共享身份验证、 session 管理等的最佳方法是什么。我们正在运行 Tomcat,并且更愿意将移动站点和桌面站点的应用程序保持在不同的节点上。 我看过类似的帖子,
我发现了这个单例的实现。我怎样才能创建指向它的指针或共享指针?` 为什么这不起作用?自动测试 = Singleton::Instance(); class Singleton { public: st
我有一个 heroku 项目,我想与其他人分享。作为the instructions describe ,我使用 virtualenv 来管理环境和依赖项。有没有办法在新机器上从 requiremen
Maven 将所有 jar 存储在本地存储库 ~/.m2/repository/ 下。用户多时占用空间大。 那么,是否可以由多个用户共享这个本地存储库,或许在不同的目录结构下? 最佳答案 简单的回答
为什么共享 worker 在重新加载页面时死了?应该是复活了我该如何解决这个问题? 重装前 重新加载后(在example.com上按F5) parent worker var port = new S
我正在开发多个小型应用程序,这些应用程序将共享通用和共享模块和 Assets 。 关于如何创建项目结构的部分在这里回答:https://stackoverflow.com/a/61254557/135
我在 RHEL 上安装了 jenkins (localhost:8080),我能够成功地构建代码 现在,我想设置主/从代理。 我的笔记本电脑将充当“Master Jenkins”,而我同事的笔记本电脑
我有这种方法可以根据我使用的 EXTRA_STREAM 共享文本文件或图片。我有这两个我可以选择 i.putExtra(Intent.EXTRA_STREAM, uri); i.putExtra(In
我正在使用 R 中的一个数据分析项目,我正在使用 R 中的敏感私有(private)数据进行一些逻辑和多级建模。我爱上了 。预订 包,我已经创建了一本关于我们的工作流程和分析管道的相当广泛的书。问题是
我正在构建的应用程序需要在 UITabBarController 框架内为多个 View (及其 subview )显示共享的自定义 UIToolbar。自定义工具栏的内容在所有 View 中都是相同
我有多个应用程序,我想共享相同的 eslint 配置: - project_root/ - app1/ - node_modules/ - eslint.rc
我有多个 Electron 应用程序。一个是主应用程序,其他几个功能应用程序。主应用程序上的按钮很少,这将导致功能应用程序打开。这里的问题是每个应用程序都有一个主进程,该进程导致要利用更多的CPU。是
我正在开发一个 Node.js 后端,它通过 websocket 与一些桌面客户端进行通信,而服务器端的通信是从 Web 前端发起的。一切正常,因为我将 SockJS Connection 实例存储在
我对托管多个网站的服务器上的多个用户帐户使用私有(private) SSH key 和无密码条目。 我为每个用户帐户使用相同的私钥。 (因为我很懒?或者那是“正确”的方式)。 我现在想授权该国不同地区
我是一名优秀的程序员,十分优秀!