【C++】STL——容器适配器priority_queue(优先级队列)详解 及 仿函数的介绍和使用

news2024/11/24 9:38:06

文章目录

    • 1. priority_queue的介绍和使用
      • 1.1 priority_queue的介绍
      • 1.2 priority_queue的使用
        • 1.2.1 仿函数介绍
        • 1.2.2 在OJ中的使用:数组中的第K个最大元素
            • 思路1:排序
            • 思路2:priority_queue
            • 思路3:TOP-K思想
    • 2. priority_queue的模拟实现
      • 2.1 核心接口
      • 2.2 向上调整
      • 2.3 向下调整
      • 2.4 仿函数less和greater模拟实现及使用
    • 3. priority_queue 存放自定义类型数据
    • 4. 拓展

这篇文章我们接着上一篇的内容,再来学一个STL里的容器适配器——priority_queue(优先级队列)

1. priority_queue的介绍和使用

1.1 priority_queue的介绍

我们上一篇文章学了queue(队列),那优先级队列也是在<queue>里面的:
在这里插入图片描述

queue一样,priority_queue也是一个容器适配器,那他和queue有什么区别呢?我们一起来认识一下priority_queue
在这里插入图片描述

  1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。
  2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。
  3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。
  4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:
    empty():检测容器是否为空
    size():返回容器中有效元素个数
    front():返回容器中第一个元素的引用
    push_back():在容器尾部插入元素
  5. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指定容器类,则使用vector。
  6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、push_heap和pop_heap来自动完成此操作。

在这里插入图片描述
首先我们看到它的默认底层容器不再是deque了,而是vector
在这里插入图片描述
当然不是只能用vector,只要支持这些操作的容器都可以,另外我们看到他对容器的迭代器是有要求的,要求得是随机迭代器random access iterators

那现在问一下大家,听到优先级队列有没有感到有点熟悉?

或者我们可以来看一下它的成员函数:
在这里插入图片描述
有没有感觉有点熟悉?
🆗,这不就是我们之前数据结构学过的堆嘛(如果大家之前没有了解过堆或者遗忘了可以去看一下之前的文章)
在这里插入图片描述
在这里插入图片描述
我们在讲解堆的时候也提到过,优先级队列就是堆。

1.2 priority_queue的使用

优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。注意:默认情况下priority_queue是大堆。
在这里插入图片描述

经过数据结构阶段的学习,这些常见的接口我们是可以直接上手使用的,其它的接口如果后续用到大家可以自己查阅文档,这里就不展开介绍了。

【注意】
默认情况下,priority_queue是大堆(大的优先级高)

我们来验证一下:

int main()
{
	priority_queue<int> q;
	q.push(1);
	q.push(0);
	q.push(5);
	q.push(2);
	q.push(1);
	q.push(7);
	while (!q.empty())
	{
		cout << q.top() << " ";
		q.pop();
	}
	cout << endl;

	return 0;
}

看一下结果:

在这里插入图片描述

那如果我们想使用小堆怎么做呢?

🆗,这时候就要用到一个东西叫做仿函数
怎么做呢?
在这里插入图片描述
我们要多传一个参数,即对应第三个模板参数。
不过呢,因为Compare 这个模板参数被设计在了第三个位置,所以我们要传第三个的话,也要传一下第二个。
那我们现在优先级队列里面放的是整型,就可以传一个greater<int>,让它变成大堆:
在这里插入图片描述

int main()
{
	priority_queue<int, vector<int>, greater<int>> q;
	q.push(1);
	q.push(0);
	q.push(5);
	q.push(2);
	q.push(1);
	q.push(7);
	while (!q.empty())
	{
		cout << q.top() << " ";
		q.pop();
	}
	cout << endl;

	return 0;
}

那这个地方大家可能有这样的疑惑:

在这里插入图片描述
我们看到第三个模板参数给的缺省值是less <value_type>,less不是较小的意思嘛,但是默认对应的却是大堆;而我们把它变成小堆传的是 greater <value_type>,而greater却是较大的意思。
那除此之外:
在这里插入图片描述
第二个模板参数是不是放到第三个位置比较好一点啊,因为默认容器我们一般不会去动它,但是第三个参数控制这个优先级,我们可能需要经常换,那这样我们传递三个参数的时候就必须把第二个也传上,但第二个一般我们不需要动,用默认的就是比较好的。
所以这个地方感觉设计的好像不是很好。

1.2.1 仿函数介绍

然后我们来解释一下这里用到的 greater<int>是个啥?
那我们先来认识一个东西——仿函数
在这里插入图片描述
他也是STL的六大组件之一。
那什么是仿函数呢?
在这里插入图片描述
🆗,仿函数(又称函数对象)其实就是一个类重载了(),使得这个类的使用看上去像一个函数。

举个栗子:

我们来写一个判断小于的仿函数,怎么做呢?
定义一个类,重载一下()就行了,函数体的实现根据我们的需求去写:
在这里插入图片描述
ps:也可以用class,区别只是它的的默认访问限定符不同。
那我们来用一下这个仿函数:
在这里插入图片描述
1小于2为真,所以打印结果为1。
🆗,那如果我们只看这一行:
在这里插入图片描述
是不是就像是一个函数调用啊。
当然它本质是去调用了类里面的operator()

那要告诉大家的是仿函数它的作用和价值还是很大的,不过我们现在还不能很好的体会到。
C++其实本质搞出这个东西是因为函数指针太复杂了,而仿函数在很多场景能达到一个替代函数指针的作用。
就比如我们这里优先级队列控制这个大堆小堆,我们之前实现过堆,我们知道控制大堆小堆其实就是就是控制里面元素的比较方式不同。
那我们C语言解决这样的问题是不是就是去传一个函数指针嘛,就比如C语言里面那个qsort函数:
在这里插入图片描述
它是不是就是通过传递一个函数指针来控制元素的比较方式啊。
而C++的sort就可以传仿函数去控制:
在这里插入图片描述
当然不是只能传仿函数,我们看到它给的是一个模板。

那我们上面用到的greater包括默认给的less其实就是库里面提供的仿函数。

当然我们看到它可以写成这样greater<int>,那库里面的其实是实现成模板了。
在这里插入图片描述
而我们刚才这样写的是只针对整型,如果像比较任意类型我们就可以将他实现成模板:
在这里插入图片描述

1.2.2 在OJ中的使用:数组中的第K个最大元素

下面我们来看一个题:数组中的第K个最大元素
在这里插入图片描述

思路1:排序

那这道题我们最容易想到的方法应该就是堆数组排个序,如果数组是有序的,那我们想拿到第k个最大的元素,不是轻而易举嘛。
那直接用sort排序就行了,要注意sort默认是升序。

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        sort(nums.begin(),nums.end());
        return nums[nums.size()-k];
    }
};

在这里插入图片描述
但是题目要求时间复杂度为 O(n) ,那我们还有没有其它更好的算法呢?

思路2:priority_queue

🆗,我们是不是可以考虑使用优先级队列(堆)来搞啊。

那我们现在要使用优先级队列的话,还需要自己写吗?
是不是可以直接用啊——priority_queue
怎么做呢?
那我们知道它默认是大堆,那我们就用大堆,首先我们拿数组的数据建堆,怎么建?
在这里插入图片描述
我们可以选择这个迭代器区间的这个构造函数。
拿建好堆之后,默认是大堆,那我们就可以pop k-1次,然后堆顶的那个数据不就是第K个最大的数了嘛。

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int> q(nums.begin(),nums.end());
        while(--k)
        {
            q.pop();
        }
        return q.top();
    }
};

在这里插入图片描述

那这种写法的时间复杂度应该是多少呢?
🆗,应该是O(N+k*logN),大家可以自己算一下,这里建堆包括pop的时间复杂度我们之前二叉树的文章也讲过。

那还要其它方法吗?

思路3:TOP-K思想

我们还可以考虑用TOP-K的思想去解决这道题:
首先我们来复习一下TOP-K(时间复杂度是O(N*log2K))的思想,这也是我们之前文章讲过的内容:
在这里插入图片描述
那这道题我们可以怎么做呢?

我们是不是可以先拿前K个数建堆,这里我们想要获取最大得前K个,应该建小堆,然后一个个比较,不符合大小关系就调整,最终堆中得数据就是最大的前K个,那此时堆顶得数据不就是我们要的数嘛。
当然我们现在用的是库里面的priority_queue,没有向下调整这些接口,而且top返回的也是引用,也不能直接替换堆顶数据,所以我们可以先pop,然后再push。

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        //建小堆
        priority_queue<int,vector<int>,greater<int>> q(nums.begin(),nums.begin()+k);
        for(size_t i=k;i<nums.size();++i)
        {
            if(nums[i]>q.top())
            {
                q.pop();
                q.push(nums[i]);
            }
        }
        return q.top();
    }
};

在这里插入图片描述

2. priority_queue的模拟实现

那我们接下来就对priority_queue进行一个模拟实现:

那我们还是按照库里面的来,把它实现成一个容器适配器的类模板
在这里插入图片描述
那它的结构就是这样的,第三个模板参数即比较的仿函数我们放到后面再搞。

2.1 核心接口

然后先我们来实现一下它的几个核心的接口:

首先写一下push:
那我们再来复习一下,堆的push怎么搞的?
🆗,堆的逻辑结构是一个完全二叉树,其物理结构,即底层实际的存储结构是一个一维数组(我们这里使用的是vector),我们push的时候先尾插一个数据,然后是不是要对它进行向上调整啊,确保插入新数据之后它还是一个堆。
在这里插入图片描述
在这里插入图片描述
那我们待会还要实现一下向上调整。
然后pop,再来回忆一下,堆的删除怎么搞?
🆗,是不是将堆顶的数据跟最后一个数据进行交换,然后删除数组最后一个数据,再进行向下调整啊。
在这里插入图片描述
在这里插入图片描述
当然待会我们也要写一下向下调整。
然后top,那就简单了:
在这里插入图片描述
然后还有size:
在这里插入图片描述
empty:
在这里插入图片描述
然后我们回过头来把向上调整实现一下。

2.2 向上调整

向上调整怎么搞(这里我们默认先按大堆来搞),回忆一下:

怎么调?
首先进行向上调整要保证之前的数据必须是一个堆。
然后看插入的数据满足不满足对应的大小关系,不满足就进行交换,直到满足为止。

100这个结点是不是大于它的父亲啊,那大堆中大的才应该做父亲,所以呢,就应该交换100和30这两个结点。
在这里插入图片描述
那调整一次就完了吗?
如果调整一次后满足了,那确实就结束了,但是现在是不是还不满足是一个大堆啊,那就要继续调整。
100还是大于它的父亲70:
在这里插入图片描述

所以:

这个调整应该是一个循环的过程,那循环什么时候结束呢?
当调整到所有结点都满足大堆或小堆的关系时,或者需要一直调整,当插入的新数据一直交换到成为根结点时就结束了。
当然如果插入的数据直接满足,那一次也不需要调整。

我们把这种从下往上调整的算法叫做向上调整。
在这里插入图片描述

思路还是和我们之前讲的一样。

void adjust_up(size_t child)
{
	size_t parent = (child - 1) / 2;
	while (child > 0)
	{
		if (_con[child] > _con[parent])
		{
			swap(_con[child], _con[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
			break;
	}
}

2.3 向下调整

然后向下调整呢?
如何调整:

其实思路跟向上调整一样,只不过这次我们是从上往下,不符合关系的进行交换,直至使它成为一个新的大堆。

我们开始调整:

在这里插入图片描述
18在这里肯定不合适,它比自己的孩子还要小,所以要交换。
和谁交换?
34可以吗,34换到堆顶,它是不是还撑不住啊。
所以我们要选择它的孩子中大的那一个进行交换。
那在这里就是49。
在这里插入图片描述

那现在18坐到原来49的位置,现在这个位置怎么样?

🆗,18是不是还是坐不稳啊。
还得进行交换。
选择18的孩子中大的那一个交换:
在这里插入图片描述
现在是不是就可以了啊。
我们交换了两次完成了,所以这还是一个循环的过程。

那这个循环的交换过程应该什么时候停止?

是不是当交换到满足大小关系或者一直交换,直到自己成为叶子结点时结束啊。

void adjust_down(size_t parent)
{
	size_t child = parent * 2 + 1;
	while (child < _con.size())
	{
		//得出较大(小堆则较小)的那个孩子
		if (child + 1 < _con.size()
			&& _con[child] < _con[child + 1])
			child++;

		if (_con[parent] < _con[child])
		{
			swap(_con[parent], _con[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
			break;
	}
}

那我们来测试一下我们写的priority_queue

在这里插入图片描述
没问题。

2.4 仿函数less和greater模拟实现及使用

那然后呢我们把第三个模板参数加上,把仿函数实现一下:

我们刚才实现的是大堆,那我们想要小堆怎么办?
我们之前数据结构学习堆的时候就知道了,是不是把向上向下调整里面的比较的大于号换成小于就行了啊
在这里插入图片描述
但是,经过我们上面的学习以及对仿函数的介绍,我们是不是可以通过传仿函数去控制啊。
所以我们要增加一个模板参数,然后通过两个仿函数去控制比较大于还是比较小于,以此控制大堆还是小堆。
在这里插入图片描述
那怎么使用第三个参数呢?
我们这里和库里面保持一样,默认第三个参数class Compare的缺省值是仿函数less,对应的是大堆。
那这样做就可以了:
在这里插入图片描述
在这里插入图片描述
那这下我们就可以通过仿函数去控制大小堆 了。

来试一下:

现在默认用less是大堆:
在这里插入图片描述
那想要小堆怎么办?用greater就行了:
在这里插入图片描述
🆗,就好了,大家理解一下这个过程:
在这里插入图片描述
当然也可以这样写在这里插入图片描述
就是用匿名对象嘛。

3. priority_queue 存放自定义类型数据

下面我们再来研究一个问题:

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
	bool operator<(const Date& d)const
	{
		return (_year < d._year) ||
			(_year == d._year && _month < d._month) ||
			(_year == d._year && _month == d._month && _day < d._day);
	}
	bool operator>(const Date& d)const
	{
		return (_year > d._year) ||
			(_year == d._year && _month > d._month) ||
			(_year == d._year && _month == d._month && _day > d._day);
	}
	friend ostream& operator<<(ostream& _cout, const Date& d);
private:
	int _year;
	int _month;
	int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
	_cout << d._year << "-" << d._month << "-" << d._day;
	return _cout;
}

现在有一个日期类,并重载了<<><

那现在呢,我想用我们的priority_queue(优先级队列)去存我们的自定义类型数据——日期类的变量,可以吗?

我们来试一下:
在这里插入图片描述
没问题,可以,现在默认是大堆嘛,所以top是最大的那个日期。
如果换成小堆:
在这里插入图片描述
那堆顶就是最小的。
那这里为什么可以,其实是因为我们的日期类重载了><,因为它里面建堆的过程是不是要进行比较啊。
在这里插入图片描述
如果没有><的重载就不行了。
所以:
如果在priority_queue中放自定义类型的数据,用户需要在自定义类型中提供> 或者< 的重载

4. 拓展

🆗,再来看,如果是这样呢:

在这里插入图片描述
现在它里面存的是Date* 的指针,我们来看下结果:
在这里插入图片描述
好像没什么问题,不过结果好像不对。
而且:
在这里插入图片描述
我们重新编译一下,再运行
在这里插入图片描述
哎呀,怎么回事。
在这里插入图片描述
怎么结果会变化啊,为什么呢?

🆗,原因在于:

我们现在里面存的是啥,是Date* 的指针变量,那指针能比较大小嘛?
当然也可以,它是内置类型,指针比较大小的话就是去比较对应地址的大小嘛。
但是这里我们new出来的地址,它们的大小关系可认为是随机的,所以虽然可以比,但是这结果是我们想要的嘛,是不是不是啊。
我们想要的的是不是去比较它们指针指向的Date类对象的大小啊

指针是内置类型,我们也没法重载它的比较操作,那怎么办呢?

我们是不是可以使用仿函数来解决啊。
在这里插入图片描述
然后我们再运行:
在这里插入图片描述
在这里插入图片描述
就会发现结果正确并且不会变化了。
那如果要小堆,很简单,再搞一个仿函数:
在这里插入图片描述
就可以了。
所以这里我们看到有了仿函数,即使是内置类型,这里我们也可以去控制它的比较方式。

这篇文章的内容就先到这里,欢迎大家指正!!!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/555491.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++入门--缺省、函数重载、引用学习

1.缺省参数 1.1缺省参数概念 缺省参数是指在声明或定义函数时为函数的参数指定一个缺省值&#xff0c;如果在调用该函数的时候没有指定参数&#xff0c;函数会使用该参数的缺省值&#xff0c;否则使用指定的参数。 #include<iostream> using std::cout; using std::cin;…

Flutter2.x升级3.x版本遇到的问题及解决方案

项目原本使用的Flutter版本为2.5.3&#xff0c;现在要升级到3.0.5版本&#xff0c;结果升级完后项目直接编译不通过&#xff0c;报了一堆的错误&#xff0c;如果你也是这种情况&#xff0c;可以按我接下来讲的操作试一试&#xff0c;反正我就是这么解决问题的。 目录 1、升级G…

连锁管理系统有哪些功能?如何选择实用的连锁管理系统?

传统门店管理系统有很多弊端&#xff0c;各种销售数据不能实时同步、沟通效率低、分店管理困难&#xff0c;库存混乱...... 一套合适的连锁管理系统&#xff0c;能够有效解决多门店之间的管理沟通难题&#xff0c;总店可以随时随地使用手机掌控分店各种事项&#xff0c;多门店之…

云原生之深入解析Airbnb的动态Kubernetes集群扩缩容

一、前言 Airbnb 基础设施的一个重要作用是保证我们的云能够根据需求上升或下降进行自动扩缩容&#xff0c;我们每天的流量波动都非常大&#xff0c;需要依靠动态扩缩容来保证服务的正常运行。为了支持扩缩容&#xff0c;Airbnb 使用了 Kubernetes 编排系统&#xff0c;并且使…

三分钟上线你自己的Midjourney

文章尾部有demo 江湖惯例&#xff1a;先来一波感谢&#xff0c;感谢laf&#xff0c;让我们可以不使用魔法、免费接入Midjourney&#xff0c;不了解laf的请猛戳 Laf介绍 背景 laf官方最近发布了一个活动&#xff0c;活动链接&#xff0c;新手也可以接入哦&#xff01;废话不多…

优维低代码实践:页面编排优化与数据联调

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

NEEPU Sec 2023公开赛Reverse题目复现

文章目录 一.Base二.How to use python1.程序逻辑分析2.爆破flag[11]~flag[14]3.爆破sha14.sha256掩码爆破 三.IKUN检查器1.查看程序信息2.分析程序逻辑3.button1_conClick函数4.check1函数5.check2函数6.check3函数7.check4函数8.check5函数 四.junk code1.使用32位动态调试工…

[Nginx 发布项目] 打包后的项目,使用nginx发布

前提 &#xff1a;使用的 mars3d 沐瑶大佬 修改后的nginx , - 下载地址 使用的是 Mars3D三维可视化平台 | 火星科技 修改后的 nginx 发布的服务&#xff0c;确保nginx发布服务时正常 &#xff1b; 如果不是&#xff0c;那这里应该没有你想要的答案&#xff1b; 1、直接替换…

006 - RCC时钟树(一)时钟树内容

006 - RCC时钟树&#xff08;一&#xff09;时钟树内容 本节内容一定要结合RCC时钟树和官方手册学习&#xff0c;如果看不明白的话&#xff0c;建议看一下野火官方的教程&#xff0c;火哥讲这节讲的很详细&#xff0c;看一遍基本就能理解了。 上节内容中分析了启动代码&#…

Web缓存服务——Squid代理服务器应用

正向代理&#xff1a;代替客户端向服务端发送请求。 反向代理&#xff1a;代理服务端&#xff0c;将请求转发给多个服务端。 一、Squid代理服务器介绍 Squid 主要提供缓存加速、应用层过滤控制的功能。 1.1 代理的工作机制&#xff08;缓存网页对象&#xff0c;减少重复请求…

2023年,Facebook Messenger群发这样做

使用SaleSmartly的企业都知道&#xff0c;SaleSmartly&#xff08;ss客服&#xff09;能在 Facebook Messenger群发信息&#xff01;Facebook Messenger在全球最受欢迎通信软件中排名第三&#xff0c;紧追头两位的 WhatsApp和微信。善用 Facebook Messenger群发工具&#xff0c…

华为OD机试真题 Java 实现【区块链文件转储系统】【2023Q2 200分】

一、题目描述 区块链底层存储是一个链式文件系统&#xff0c;由顺序的N个文件组成&#xff0c;每个文件的大小不一&#xff0c;依次为F1,F2…Fn。 随着时间的推移&#xff0c;所占存储会越来越大。 云平台考虑将区块链按文件转储到廉价的SATA盘&#xff0c;只有连续的区块链…

为什么都在学python?

自然是因为Python简单易学且应用领域广&#xff01; Python近段时间一直涨势迅猛&#xff0c;在各大编程排行榜中崭露头角&#xff0c;得益于它多功能性和简单易上手的特性&#xff0c;让它可以在很多不同的工作中发挥重大作用。 正因如此&#xff0c;目前几乎所有大中型互联…

毕业三年月薪才21K,真是没出息......

“害&#xff0c;毕业三年月薪才拿21k,真失败&#xff0c;真的给同龄人拖后腿&#xff01;”这是人能讲出来的话&#xff1f;这就是凡尔赛天花板&#xff1f;这就是我公司的测试部门的人说出来的话&#xff0c;他计算机专业毕业三年&#xff0c;包括实习&#xff0c;在我们公司…

LeetCode:28. 找出字符串中第一个匹配项的下标

28. 找出字符串中第一个匹配项的下标 1&#xff09;题目2&#xff09;代码1.方法一&#xff1a;每个字符进行匹配2.方法二&#xff1a;截取字符串进行匹配 3&#xff09;结果1.方法一结果2.方法二结果 1&#xff09;题目 给你两个字符串 haystack 和 needle &#xff0c;请你在…

Dropwizard 开发环境搭建

Dropwizard是一个Java框架&#xff0c;其目标是提供高性能、高可靠的Web 应用程序的实现。 一、使用Maven原型创建项目 1、新建项目->选择Maven Archetype 填写好项目名称、路径、选择JDK版本&#xff0c;这里使用JDK11及以上的版本&#xff0c;如下图所示&#xff1a; 2…

自监督对比学习系列论文(一):无引导对比学习--MOCO,SimCLR

自监督对比学习 对比学习&#xff08;self-supervised learning&#xff09;的应用场景是用无标记或者少标记的数据进行模型的预训练以得到一个较好的预训练模型&#xff0c;然后便可将该模型轻松的迁移到到下游任务上。显而易见的&#xff0c;对比学习的难点在于我们如何在没有…

【论文下饭】PatchTST中的channel-independence

PatchTST中的channel-independence 总结PatchingChannel-independence A Time Series is Worth 64 Words: Long-term Forecasting with Transformers 时间&#xff1a;2022 引用&#xff1a;8 ICLR 2023 代码&#xff1a;https://github.com/yuqinie98/PatchTST 中文参考&#…

软件开发人技能变现方案来啦~

java单体服务Uniapp客户端 欢迎大家来关注java单体服务Uniapp客户端模式开发应用程序这个模式下产品的特点互联网大厂产品特点小服务小产品-存在价值普通人慢慢挣小钱 欢迎大家来关注 你好&#xff01; 这可能是你第一次来“莹未来”这里&#xff0c;郑重欢迎您。如果你想学习…

firewalld防火墙详细介绍

目录 一、firewalld概述 二、firewalld与iptables的区别 1.位置不同 2.配置存储位置不同 3.规则运行不同 4.防火墙类型不同 三、firewalld区域的概念 四、firewalld防火墙9个区域 1、trusted&#xff08;信任区域&#xff09; 2、public&#xff08;公共区域&#xf…