融合元组以查找等价类

2024-05-23

假设我们有一个包含 k 个元素的有限域 D={d1,..dk}。

我们认为 S 是 D^n 的子集,即一组 形式的元组,其中 ai 在 D 中。

我们希望使用 S' 2^D^n 的子集(即一组 形式的元组,其中 Ai 是 D 的子集)来(紧凑地)表示它。这意味着对于任何元组 s ' in S' Ai 叉积中的所有元素都存在于 S 中。

例如,考虑 D={a,b,c},因此 k=3,n=2,并且元组 S=+++。

我们可以用S'=来表示S。

这个单例解也是最小的,S'=+也是一个解,但它更大,因此不太理想。

在具体实例中,我们需要处理一些大小:域 D 中的 k ~ 1000 个元素,n 10^6 的大值。

一种朴素的方法包括首先将 S 放入 S' 2^D^n 的域中,然后使用以下测试,两两,S' 中的两个元组 s1,s2 可以融合以形成 S' 中的单个元组,当且仅当。它们仅在一个组件上有所不同。

e.g.
+ -> (第二个组件不同)

+ -> (第二个组件不同)

+ -> (第一个组件不同)

现在可能有几个最小的 S',我们有兴趣找到任何一个,并且某种最小化的近似也是可以的,只要它们不会给出错误的结果(即,即使 S' 没有那么小) ,但我们很快就能得到结果)。

朴素算法必须处理这样一个事实:任何新引入的“融合”元组都可能与其他元组匹配,因此即使 n 保持较低,它在大型输入集上的扩展性也非常糟糕。您需要 |S'|^2 比较来确保收敛,并且每当您融合两个元素时,我目前正在重新测试每一对(我该如何改进?)。

很多效率取决于迭代顺序,因此以某种方式对集合进行排序可能是一种选择,或者可能使用哈希进行索引,但我不确定如何做到这一点。

命令式伪代码是理想的选择,或者将问题重新表述为我可以运行求解器的指针会真正有帮助。


这是一些伪代码(我尚未测试过的 C# 代码),它演示了您的S'=+方法。除了空间要求外,当对元素使用整数索引时,空间要求可以忽略不计;添加和测试元组的整体效率和速度应该非常快。如果您想要一个实用的解决方案,那么您已经有了一个,只需使用正确的 ADT。

ElementType[] domain = new ElementType[]; // a simple array of domain elements
  FillDomain(domain); // insert all domain elements
  SortArray(domain); // sort the domain elements  K log K time
SortedDictionary<int, HashSet<int>> subsets; // int's are index/ref into domain
subsets = new SortedDictionary<int, HashSet<int>>();
//
void AddTuple(SortedDictionary<int, HashSet<int>> tuples, ElementType[] domain, ElementType first, elementType second) {
    int a = BinarySearch(domain, first); // log K time (binary search)
    int b = BinarySearch(domain, second); // log K time (binary search)
    if(tuples.ContainsKey(a)) { // log N time (binary search on sorted keys)
        if(!tuples[a].Contains(b)) { // constant time (hash lookup)
            tuples[a].Add(b); // constant time (hash add)
        }         
    } else { // constant time (instance + hash add)
        tuples[a] = new HashSet<in>();
        tuples[a].Add(b);
    }
}
//
bool ContainsTuple(SortedDictionary<int, HashSet<int>> tuples, ElementType[] domain, ElementType first, ElementType second) {
    int a = BinarySearch(domain, first); // log K time (binary search)
    int b = BinarySearch(domain, second); // log K time (binary search)
    if(tuples.ContainsKey(a)) { // log N time (binary search on sorted keys)
        if(tuples[a].Contains(b)) { // constant time (hash test)
            return true;
        }
    }
    return false;
}

优化元组子集 S' 所节省的空间不会超过优化过程本身的减慢。对于大小优化(如果您知道 K 将小于 65536,您可以在 SortedDictionary 和 HashSet 中使用短整数而不是整数。但即使是 5000 万个整数,每个 32 位整数也只占用 4 个字节 * 5000 万 ~= 200 MB 。

EDIT这是另一种方法,通过将元组编码/映射到字符串,您可以利用二进制字符串比较以及 UTF-16 / UTF-8 编码非常节省空间的事实。同样,这仍然没有达到您想要的合并优化,但速度和效率会相当不错。

这是 JavaScript 中的一些快速伪代码。

Array.prototype.binarySearch = function(elm) {
  var l = 0, h = this.length - 1, i; 
  while(l <= h) { 
    i = (l + h) >> 1; 
    if(this[i] < elm) l = ++i; 
    else if(this[i] > elm) h = --i; 
    else return i; 
  } 
  return -(++l); 
};
// map your ordered domain elements to characters 
// For example JavaScript's UTF-16 should be fine
// UTF-8 would work as well
var domain = {
  "a": String.fromCharCode(1),
  "b": String.fromCharCode(2),
  "c": String.fromCharCode(3),
  "d": String.fromCharCode(4)
}
var tupleStrings = [];
// map your tuple to the string encoding
function map(tuple) {
  var str = "";
  for(var i=0; i<tuple.length; i++) {
    str += domain[tuple[i]];
  }
  return str;
}
function add(tuple) {
  var str = map(tuple);
  // binary search
  var index = tupleStrings.binarySearch(str);
  if(index < 0) index = ~index;
  // insert depends on tupleString's type implementation
  tupleStrings.splice(index, 0, str);
}
function contains(tuple) {
  var str = map(tuple);
  // binary search 
  return tupleString.binarySearch(str) >= 0;
}

add(["a","b"]);
add(["a","c"]);
add(["b","b"]);
add(["b","c"]);
add(["c","c"]);
add(["d","a"]);
alert(contains(["a","a"]));
alert(contains(["d","a"]));
alert(JSON.stringify(tupleStrings, null, "\n"));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

融合元组以查找等价类 的相关文章

  • 为什么《破解编码面试》这个例子的时间复杂度是O(k c^k)?

    该问题来自 破解编码面试 第 6 版 问题 V1 11 以下代码打印长度为 k 的所有字符串 其中字符 是按排序顺序排列的 它通过生成所有长度的字符串来做到这一点 k 然后检查每个是否已排序 什么是运行时间 package QVI 11 P
  • 直观地执行不同的排序算法[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 图像算法上的物体计数

    我又接到学校任务了 这次 我的老师给我的任务是创建算法来计算图片上有多少只鸭子 该图与此类似 我想我应该使用模式识别来搜索上面有多少只鸭子 但我不知道每只鸭子适合哪种图案 我认为你可以通过分割鸭嘴并计算鸭嘴的数量来解决这个问题连接的组件 h
  • 神经网络的层和神经元

    我想更多地了解神经网络 我正在开发一个 C 程序来制作神经网络 但我坚持使用反向传播算法 很抱歉没有提供一些工作代码 我知道有很多库可以用多种语言创建神经网络 但我更喜欢自己制作一个 关键是我不知道要实现特定目标 例如模式识别或函数近似或其
  • 计算字符串的所有子串中子序列的出现次数

    我想编写一个算法来计算字符串的所有子字符串中字符子序列 不相交 出现的总数 下面是一个例子 字符串 jabcohnnyjohnny 后续 约翰尼 包含子序列的子字符串 jabcohnny jabcohnnyj jabcohnnyjo jab
  • 线段树java实现[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 你知道 二进制 的良好实现吗线段树 http en wikipedia org wiki Segmen
  • 简单的排名算法

    我需要创建一个民意调查 按照项目的好坏顺序创建一个排名列表 我打算向每个用户展示两个项目 让他们选择一个他们认为更好的项目 然后多次重复这个过程 它有点类似于您在社交网络电影 我应该如何根据收到的答案对项目进行排名 看着那 这ELO国际象棋
  • 关于Marching Cubes算法的澄清

    关于Marching Cubes 我对其算法和实现有一些疑问 我已经阅读了 Marching Cubes 的 Paul Bourke 优秀文章以及网站上可用的源代码 但是 我在理解以及如何以自己的方式实现算法方面仍然遇到了一些问题 问题如下
  • Python Pandas:沿一列比较两个数据帧,并返回另一个数据帧中两个数据帧的行内容

    我正在处理两个 csv 文件并作为数据框 df1 和 df2 导入 df1 有 50000 行 df2 有 150000 行 我想将 df2 的 时间 与 df1 求时间差并返回所有列的值 对应相似的行 保存在df3中 时间同步 例如 35
  • 分而治之算法找到两个有序元素之间的最大差异

    给定一个整数数组 arr 找出任意两个元素之间的差异 使得较大的元素出现在 arr 中较小的数字之后 Max Difference Max arr x arr y x gt y 例子 如果数组是 2 3 10 6 4 8 1 7 那么返回值
  • 坐标算法 - 绕中心旋转

    通过查看这张图片 我想您会很好地理解我的问题 图片已删除 网址不再有效 现在返回广告 所以基本上我想要一个函数 它接受一个对象作为参数 并根据我之前添加的对象数量为该对象提供正确的坐标 假设我将所有这些对象添加到一个数组中 objectAr
  • 如何光栅化旋转矩形(通过 setpixel 在 2d 中)

    我有四个 2d 顶点 A B C D 的旋转矩形 我需要在像素缓冲区中 有效地 光栅化 绘制它 使用 setpixel x y 颜色 怎么做 我正在尝试使用一些代码 例如 convertilg a b c d do up down left
  • 测试 python Counter 是否包含在另一个 Counter 中

    如何测试是否是pythonCounter https docs python org 2 library collections html collections Counter is 包含在另一个中使用以下定义 柜台a包含在计数器中b当且
  • 连接红黑树

    OCaml 标准库有一个很棒的Set使用非常有效的分而治之算法来计算的实现union两套 我相信它会从一组中获取整个子树 而不仅仅是单个元素 并将它们插入到另一组中 并在必要时重新平衡 我想知道这是否需要 OCaml 使用的 AVL 树中保
  • 当满足动态条件时退出递归函数

    使用来自的函数生成汉明距离 t 内的所有比特序列 https stackoverflow com questions 40813022 generate all sequences of bits within hamming distan
  • 我如何开始玩五子棋?

    我读到Gomoku http en wikipedia org wiki Gomoku它可以使用 Minimax 和 Alpha Beta 剪枝算法来实现 所以 我阅读了这些算法 现在了解了游戏将如何解决 但是当我坐下来编写代码时 我面临着
  • 查找字符串中最常见的子字符串的算法

    是否有任何算法可用于查找字符串中最常见的短语 或子字符串 例如 以下字符串将 hello world 作为其最常见的两个单词短语 hello world this is hello world hello world repeats thr
  • 密文窃取算法 - 哪一种是正确的?

    网络上提出了两种算法 在这两种算法中 第一部分是相同的 1 Pad the last partial plaintext block with 0 2 Encrypt the whole padded plaintext using the
  • 用于在链表中查找结点的生产代码

    我在一次采访中被问到这个问题 我被要求编写代码 用于在 O 1 空间和线性时间的生产环境中在链表 其形式为 Y 形式 双臂不一定相等 中查找结点 我想出了这个解决方案 我以前在某处见过 1 Measure lengths of both l
  • 添加边后更新最大流量

    考虑我们有一个网络流量 并使用 Edmond Karp 算法 我们已经拥有网络上的最大流量 现在 如果我们向网络添加任意边 具有一定容量 更新最大流量的最佳方法是什么 我正在考虑更新关于新边缘的残差网络 并再次寻找增强路径 直到找到新的最大

随机推荐

  • 如何在WinMobile6上启用ARMv6非对齐访问?

    ARMv6 引入了一个很棒的功能 未对齐的内存访问 这使得代码中的某些事情变得更加简单和更快 但微软只在winCE6中提供了API 现在大多数 PDA 都基于 WinMobile6 基于 CE 5 x 默认情况下禁用未对齐访问 我尝试在 C
  • 从标记访问 json 属性 - gmaps4rails

    我正在升级到 gmaps4rails v2 我似乎无法从 javascript 访问标记 json 属性 这在我使用的先前版本 1 5 6 中有效 具体来说 内置控制器 users User all hash Gmaps4rails bui
  • Go客户端程序生成大量TIME_WAIT状态的socket

    我有一个 Go 程序 它从多个 goroutine 生成大量 HTTP 请求 运行一段时间后 程序报错 connect cannot allocaterequestedaddress 当检查时netstat 我得到大量 28229 个连接T
  • Powershell:获取 FQDN 主机名

    我想通过 powershell 脚本检索 Windows 服务器的 FQDN 名称 到目前为止我已经找到了2个解决方案 server Invoke Command ScriptBlock hostname 上面的行将仅打印服务器的短名称 s
  • 64 位 pyodbc 是否可以与 32 位 MS Access 数据库对话?

    我正在使用 64 位 python anaconda v4 4 它运行 python v3 我有 MS Access 2016 32 位版本 我想使用 pyodbc 让 python 与 Access 对话 是否可以使用 64 位 pyod
  • git push --force-with-lease 总是安全吗?

    我一直遵循的规则是 一旦 git 历史记录被推送到远程存储库 就不再修改它 但我想知道交互式变基到推送 force with lease 是否绕过了这条规则 如果强制租约成功 对其他用户来说是否完全安全 或者此策略有任何注意事项吗 预先感谢
  • Scala 正则表达式替换为匿名函数

    在 Ruby 中 我可以通过以下方式替换字符串中的字符 a one1two2three a gsub d e e to i 1 gt one2two3three 从第二行开始评估块的结果将替换模式中匹配的内容 我们可以在 Scala 中做类
  • 随机显示 NoMethodError:未定义的方法“空?”对于 0:Fixnum

    它在我的本地计算机上运行良好 但使用 Puma Web 服务器在 Heroku 上的rails admin 中出现以下错误 这是我使用 enumerize 的方式 enumerize date type in last date 0 beg
  • Nuget 3.5 在打包时去掉前导零[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在 v3 5 中 行为发生了变化 因此当它打包一个包时 它会去掉前导零 这不是我们想要的行为 希望 v3 6 能修复这个问题 正如上所解释
  • .NET 中安全身份的本地化

    我想在 NET 中实现一个用于服务 客户端通信的命名管道 并遇到了这段代码 http code msdn microsoft com windowsdesktop CSNamedPipeCommunication 33b2485c view
  • 如何使用 forkjoin 返回 Angular 中两个独立 API 调用的组合响应

    我有两个独立的 api 调用 下面是两个api调用的代码 public getLendingType partyId string Observable lt lendingType string partyId string gt ret
  • 如何以编程方式打开 Run c++?

    问题是如何从 C 以编程方式打开 Run 我知道有一些功能可以替代它 例如 shellexec winexec 但对于某些任务 我只需要出现 运行 对话框 运行对话框位于 shell32 dll 中 使用该函数RunFileDlg 显示对话
  • 为什么表达式“1”==1 的计算结果为 TRUE? [复制]

    这个问题在这里已经有答案了 1 是字符值 其他1是数字 甚至 当我尝试在下面执行时 它给了我 TRUE as character 0 as numeric 0 谁能帮助我理解 为什么 来自help 如果两个参数是不同类型的原子向量 则其中一
  • Selenium Webdriver 和 Java。元素在点 (x, y) 处不可单击。其他元素将收到点击

    我使用显式等待并收到警告 org openqa selenium WebDriverException 元素在点 36 72 处不可单击 其他元素将收到 点击 命令持续时间或超时 393 毫秒 如果我使用Thread sleep 2000
  • 如何在 Java 中将帧速率限制为 60 fps?

    我正在编写一个简单的游戏 我希望将帧速率限制在 60 fps 而不会让循环占用我的 CPU 我该怎么做 您可以阅读游戏循环文章 https dewitters com dewitters gameloop 在尝试实现任何内容之前 首先了解游
  • 如何在“order by”中添加条件?

    我有一个带有输入参数的存储过程 现在根据这个参数 我的 order by 语句将发生变化 如果输入参数是 ID int类型列 则按ID排序 如果是 ProductType 则按产品类型排序 如果是 IssueDate 则应按问题日期排序 现
  • 迁移问题:MS SQL > MySQL:插入缓冲区内存

    我在使用 MySQL Workbench 上的内置迁移工具时遇到问题 我正在将一个非常大的数据库从 MS SQL 2014 迁移到 MySQL MS SQL 服务器本地部署在我的 Windows 8 1 桌面上 MySQL 服务器在我的网络
  • 用 PHP 截断文件末尾

    我有一个日志文件 我想在 PHP 读取该文件后将其截断 我的代码目前如下所示 fp fopen file r ftruncate fp 125000 fclose fp 但是 这会通过保留first1MB 不过 我想保留last1Mb 的文
  • .NET 正则表达式可匹配任何语言的任何类型的字母

    我可以使用哪种正则表达式来匹配 允许 任何语言的任何类型的字母 我需要匹配任何字母 包括任何变音符号 例如 并排除任何类型的符号 数学符号 货币符号 装饰符号 方框图字符等 和标点符号 我正在使用 ASP NET MVC 2 和 NET 4
  • 融合元组以查找等价类

    假设我们有一个包含 k 个元素的有限域 D d1 dk 我们认为 S 是 D n 的子集 即一组 形式的元组 其中 ai 在 D 中 我们希望使用 S 2 D n 的子集 即一组 形式的元组 其中 Ai 是 D 的子集 来 紧凑地 表示它