0

0

子集相等性是NP完全的

王林

王林

发布时间:2023-08-28 23:41:06

|

1605人浏览过

|

来源于tutorialspoint

转载

子集相等性是np完全的

商达讯网店系统豪华版
商达讯网店系统豪华版

sdxShop是一款完全开源免费的网上独立建店系统,asp+access,程序经过专业团队开发升级发展了7年,功能和安全性已经达到非常成熟稳定,安装容易,一分钟就可以搭起专业的电子商务网站。该免费版功能完整永久免费,主要特色功能淘宝数据表导入,实现网店和淘宝网店数据统一,拓展网店经营策略,提供5种在线支付接口等等。

下载

子集对应,也称为“子集总计”问题,是一个示例性的 NP 完全计算问题。给定一堆数字和一个客观价值,任务是确定是否存在其总数等于客观价值的数字子集。该问题的 NP 顶峰源于其通过多项式时间递减来解决各种其他 NP 完全问题的能力。不管其简单的定义如何,没有一种有效的计算可以解决所有事件的“子集对应”,这使得它在假设的软件工程和简化中具有重要意义,并且在不同领域(如密码学、资产分配和动态问题)具有功能应用。

使用的方法

  • 子集总和的减少

  • 从 3SAT 减少

从子集总和中减少

处理“子集公平性”是 NP 完成问题的一种方法是显示显着的 NP 完成问题(“子集总数”问题)的减少。

算法

  • 给定一个“子集聚合”问题的案例,它是一堆整数 S 和一个价值 T 的目标。

  • 使用类似的集合 S 和目标自尊 2T 来制作“子集权益”问题的另一个案例。

  • 如果在“子集聚合”问题中存在 S 的子集汇总为 T,那么此时,“子集均匀性”问题中将存在一个汇总为 T 的子集2T 通过添加与其自身相似的子集。

  • 假设在“子集总计”问题中不存在 S 的子集汇总为 T,那么在“子集公平性”问题中也不存在汇总为 2T 的子集,因为任何具有总计的子集低于2T的与其自身相加不能超过2T。

  • 这种下降表明解决“子集公平性”问题与解决“子集聚合”问题几乎一样困难,使其成为 NP 完全问题。

示例

#include 
#include 
using namespace std;

bool isSubsetSum(vector& set, int n, int sum) {
   if (sum == 0) return true;
   if (n == 0) return false;

   if (set[n - 1] > sum) return isSubsetSum(set, n - 1, sum);

   return isSubsetSum(set, n - 1, sum) || isSubsetSum(set, n - 1, sum - set[n - 1]);
}

bool isSubsetAggregateReduction(vector& set, int n, int sum) {
   return !isSubsetSum(set, n, sum) && !isSubsetSum(set, n, 2 * sum);
}

int main() {
   vector set = {3, 34, 4, 12, 5, 2};
   int sum = 18; 
   if (isSubsetAggregateReduction(set, set.size(), sum)) {
      cout << "No subset exists in Subset Aggregate issue that sums to " << sum << " and no subset exists that sums to " << 2 * sum << " by adding the same subset with itself." << endl;
   } else {
      cout << "There exists a subset in Subset Aggregate issue that sums to " << sum << " or a subset in Subset Equity issue that sums to " << 2 * sum << " by adding the same subset with itself." << endl;
   }

   return 0;
}

输出

There exists a subset in Subset Aggregate issue that sums to 18 or a subset in Subset Equity issue that sums to 36 by adding the same subset with itself.

从 3SAT 减少

另一种方法是通过直接从一个已知的 NP 完全问题(例如 3SAT 问题)中减去它来证明“子集对应”是 NP 完成的。

算法

  • 给出了 3SAT 问题的示例,其中包含一个联合普通结构中的布尔配方,每个条件具有三个文字。

  • 用一堆整数和目标值再讨论一下“子集均匀性”问题,如下所示:

  • a.对于 3SAT 方程中的每个变量,在集合中创建一个值为 1 的数字。

    b.对于 3SAT 方程中的每个附加条件,在集合中生成一个值为 2 的数字。

    c.将目标值设置为 3SAT 配方中的全部附加条件和所有因素的全部数量。

  • 如果 3SAT 方案可满足,则“子集均匀性”问题中存在一个子集,该子集通过为每个已满足的条件选择一个变量来总结目标值。

  • 如果 3SAT 配方无法满足,那么“子集对应”问题中就没有子集可以概括为目标值,因为任何合法子集都必须包含不少于一个值为 2 的整数,与已履行的条款相关。

  • 由于已知 3SAT 问题是 NP 完成的,因此这种下降表明“子集股权”的 NP 顶峰。

示例

#include 
#include 
using namespace std;

bool ThreeSAT_Satisfiable(const vector>& clauses) {
   return false;
}

class SubsetUniformity {
private:
   vector numbers;
   int targetValue;

public:
   SubsetUniformity(const vector& vars, const vector& clauses) {
      for (int v : vars) {
         numbers.push_back(1);
      }
      for (int c : clauses) {
         numbers.push_back(2);
      }
      targetValue = vars.size() + clauses.size();
   }

   bool isSubsetSumPossible(int idx, int sum) {
      if (sum == targetValue) {
         return true;
      }
      if (idx >= numbers.size() || sum > targetValue) {
         return false;
      }
      return isSubsetSumPossible(idx + 1, sum) || isSubsetSumPossible(idx + 1, sum + numbers[idx]);
   }

   bool hasSolution() {
      return isSubsetSumPossible(0, 0);
   }
};

int main() {
   vector> clauses = {
      {1, 2, -3},
      {-1, -2, 3},
      {-1, 2, 3}
   };

   bool isSatisfiable = ThreeSAT_Satisfiable(clauses);
   SubsetUniformity su(clauses[0], clauses[1]);

   cout << "3SAT Formula is " << (isSatisfiable ? "satisfiable." : "not satisfiable.") << endl;
   cout << "Subset Uniformity has " << (su.hasSolution() ? "a" : "no") << " solution." << endl;

   return 0;
}

输出

3SAT Formula is not satisfiable.
Subset Uniformity has a solution.

结论

这两种方法都表明“子集权益”或“子集聚合”问题是 NP 完成的,因此,跟踪有效的计算来解决所有示例的问题是不可能的。科学家经常利用动态规划或其他估计程序来有效地解决此问题的可行情况。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

393

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

574

2023.08.10

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

404

2023.08.14

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

56

2026.01.21

三角洲入口地址合集
三角洲入口地址合集

本专题整合了三角洲入口地址合集,阅读专题下面的文章了解更多详细内容。

28

2026.01.21

AO3中文版入口地址大全
AO3中文版入口地址大全

本专题整合了AO3中文版入口地址大全,阅读专题下面的的文章了解更多详细内容。

385

2026.01.21

妖精漫画入口地址合集
妖精漫画入口地址合集

本专题整合了妖精漫画入口地址合集,阅读专题下面的文章了解更多详细内容。

116

2026.01.21

java版本选择建议
java版本选择建议

本专题整合了java版本相关合集,阅读专题下面的文章了解更多详细内容。

3

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
微信小程序开发之API篇
微信小程序开发之API篇

共15课时 | 1.2万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

c语言项目php解释器源码分析探索
c语言项目php解释器源码分析探索

共7课时 | 0.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号