拟阵

拟阵一 拟阵 1 拟阵换句话说 拟阵是一种满足遗传性和交换性的子集族

大家好,欢迎来到IT知识分享网。

目录

一,拟阵

1,拟阵

2,拟阵性质

3,独立子集的扩张

4,常见拟阵

5,图的拟阵

6,互补拟阵

二,加权拟阵

1,加权拟阵

2,最优子集

3,贪心问题的拟阵模型

4,求最优子集的通用算法

三,应用实例

单个处理器上对若干个单位时间任务的最优调度问题


一,拟阵

1,拟阵

拟阵

换句话说,拟阵是一种满足遗传性和交换性的子集族。

2,拟阵性质

对于第二条,可以这么理解:

如果我们把I中不是I中其他任何元素的子集的元素,称为最大独立子集,那么最大独立子集的数量至少为1,而这些最大独立子集可以完全定义出I

因为任意一个最大独立子集的所有子集都是I的元素,而且这些子集就包含了I的所有元素。

对于第三条,其实就是给这些最大独立子集加以限定。

首先,所有最大独立子集的元素个数都是一样的

其次,如果构造一个图,每个节点对应一个最大独立子集,2个最大独立子集如果只有一个元素不同那么就连接一条边,那么这个图是无向连通图

最后,这个无向连通图是否还具有其他性质?比如含有哈密顿链路或环路?这个不太确定。

3,独立子集的扩张

如果x\notin A,\,A\cup{x}\in I,那么称x为A的扩张

4,常见拟阵

(1)S={1,2,3,4},I有9个元素{1,2}{1,3}{2,4}{3,4}{1}{2}{3}{4}{},其中{1,2}{1,3}{2,4}{3,4}是4个最大独立子集。

那么M=(S,I)就是一个简单的拟阵。

(2)S={1,2,3,4},I有11个元素{1,2}{1,3}{1,4}{2,3}{2,4}{3,4}{1}{2}{3}{4}{},其中{1,2}{1,3}{1,4}{2,3}{2,4}{3,4}是6个最大独立子集。

那么M=(S,I)就是一个简单的拟阵。

(3)显然(2)中的拟阵是非常简单的一种拟阵,可以直接推广:

拟阵

(4)矩阵拟阵

拟阵

(5)不那么显然的,(1)中的拟阵可以推广成:

拟阵

5,图的拟阵

拟阵

即S是一个图,它的所有无环边集构成一个拟阵。

根据图的性质很容易证明,这确实是拟阵,证明略。

对于一个全连通的图,最大独立子集就是生成树,元素个数就是 顶点数-1

6,互补拟阵

拟阵

二,加权拟阵

1,加权拟阵

S中的每个元素都有一个权值,一个独立子集的权是它的所有元素的权之和

拟阵

例如,图的拟阵中,权是边的长度,独立子集的权是所有包含的边的长度之和。

这里就得到了它和最小生成树的关系:对于一个全连通的图,如果每条边的权都大于0,那么权最小的最大独立子集就是最小生成树

2,最优子集

给定一个加权拟阵,所有元素的权都是正数,我们把具有最大权值的独立子集,称为最优子集。

因为所有元素的权值都是正数,所以最优子集一定是最大独立子集。

3,贪心问题的拟阵模型

很多贪心问题都可以转化成一个拟阵模型,即求最优子集。

例如求最小生成树,假设所以的边的权值都在(0,c)范围内,我们把所有边的权值乘以-1,再加上c,即从x变成c-x,

那么求最小生成树的问题,就转化成了求最大权值的最大独立子集,即求最优子集。

4,求最优子集的通用算法

拟阵

算法非常简单,把所有元素按照权值递减排序,然后从头到尾扫描一遍,

独立子集A初始化为空集,扫描的过程中,如果A加上当前元素还是独立子集,那就加上,如果不是那就不加,

扫描完之后,就得到了最优子集。

实现:

#include<iostream> #include<vector> #include<algorithm> using namespace std; typedef struct Node //需要根据实际修改 { int w; }Node; #define N 100 //需要根据实际修改数值 Node s[N]; bool cmp(Node &a,Node &b) { return a.w>b.w; } template<typename T> bool check(vector<T>&A)//判断是否是独立子集 { return true; //需要根据实际修改逻辑 } vector<Node> greedy()//求最优子集 { vector<Node>A; sort(s,s+N,cmp); for(int i=0;i<N;i++){ A.push_back(s[i]); if(!check(A))A.pop_back(); } return A; } int main() { return 0; } 

其中,需要根据实际进行修改的有三处:规模N、结构体Node、判断是否是独立子集的函数check

时间复杂度:O(nlogn+nf(n)),其中f(n)是check函数运行的时间。

三,应用实例

单个处理器上对若干个单位时间任务的最优调度问题

拟阵

拟阵

思路:

首先,一个调度可以表示成早任务都在迟任务的前面的形式,早任务指的是能及时完成的任务。

其次,在早任务都在迟任务的前提下,一个调度可以表示成早任务全都是按照期限递增的形式。

所以,一个调度等价于一个早任务的集合。

那么,如何判断一个集合是不是独立集合呢?即如何实现check函数?

拟阵

根据(2)即可完成check函数,时间复杂度为O(n)

所以整个算法的时间复杂度为O(n^2)

思路二:

如果不用拟阵,按照常规的贪心思路,把任务按照权值递减排序,然后从头到尾扫描,依次决定每个任务放到哪个位置,

如果当前还有时间槽可以完成这个任务,那就用其中最近(时间最靠后)的时间槽来完成这个任务,如果没有,那这个任务就是迟任务,不用调度了。

这个选时间槽的操作可以用并查集来完成:如还剩2个槽3,7,那么就有3棵树,根分别为0,3,7,成员分别是{0,1,2}{3,4,5,6}{7…},

这样就能根据任务的期限快速找出最近时间槽了。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/128397.html

(0)
上一篇 2025-08-31 20:26
下一篇 2025-08-31 20:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信