Java优先级队列(PriorityQueue)代码示例

1.基本概念

  优先级队列,根据元素的优先级进行排列和访问,相当于根据元素的优先级进行自动排列,不需要我们手动去写一个代码给它排序。

 (1)创建一个队列

PriorityQueue<类型> priorityQueue = new PriorityQueue<>(按照何种优先级排列);

我们需要什么类型的队列,就可以在类型一处写上该类型名,以便创建出一个该类型的队列。优先级默认是 小顶堆 (Min Heap),从小到大排序,如果有其他的排列需求,我们需要通过Comparator.comparing(类型名::成员名)的形式去设置队列的优先级,这样就可以根据我们自己的要求去排列了,类型应与队列的类型相同,而成员名处则写出该队列按照哪个元素的大小顺序(从小到大)进行排列的成员名。

如果我们要按照大顶堆(Max Heap)排序,则要以Comparator.comparing(类型名::成名).reversed()的形式进行排列,我们通过使用 reversed() 方法反转比较顺序,从而达到大顶堆排序的目的。

根据类型的不同,书写形式有微小的区别,如下

  • Comparator.comparing():用于创建一个基于对象属性的Comparator
  • Comparator.comparingDouble():用于创建一个基于双精度浮点数属性的Comparator
  • Comparator.comparingLong():用于创建一个基于长整型属性的Comparator

(2)操作队列

  • 如果我们要向队列中添加元素,我们可以使用 add() 方法向队列中添加元素。
  • 如果我们需要查看优先级最高的元素,有两个方法,分别是 poll() 、 peek() 方法,其中 poll() 方法是提取出优先级最高元素并且移除,而 peek() 方法则是只查看不移除。
  • 如果我们需要查看队列是否为空,可以使用 isEmpty() 方法判断 。                                                   
  • 如果我们想要知道队列的长度,可以使用 size() 方法获取队列长度。

2.代码示例

我们用学生成绩的高低举一个例子。

首先我们先写一个学生类

class Student {
    private final String name;
    private final int math;
    private final int english;
    private final int chinese;

    public String getName() {
        return name;
    }

    public int getMath() {
        return math;
    }

    public int getEnglish() {
        return english;
    }

    public int getChinese() {
        return chinese;
    }
    public int getSum() {
        return math + english + chinese;
    }

    public Student(String name, int math, int english, int chinese) {
        this.name = name;
        this.math = math;
        this.english = english;
        this.chinese = chinese;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", math=" + math +
                ", english=" + english +
                ", chinese=" + chinese +
                '}';
    }
}

然后编写一个主类

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);

        // 创建Student类的队列,按照总成绩的优先级排序
        PriorityQueue<Student> students = new PriorityQueue<>(Comparator.comparing( Student :: getSum));

        System.out.println("输入学生人数:");
        int num = s.nextInt();
        while( num > 0 ) {
            System.out.println("输入学生信息:");
            students.add( new Student( s.next(), s.nextInt(), s.nextInt(), s.nextInt()));
            num--;
        }
        for( Student t : students) {
            System.out.println(t);
        }
    }
}

我们创建了一个学生类的队列,并且按照学生的总成绩优先级排列。

3.代码综合

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);

        // 创建Student类的队列,按照总成绩的优先级排序
        PriorityQueue<Student> students = new PriorityQueue<>(Comparator.comparing( Student :: getSum));

        System.out.println("输入学生人数:");
        int num = s.nextInt();
        while( num > 0 ) {
            System.out.println("输入学生信息:");
            students.add( new Student( s.next(), s.nextInt(), s.nextInt(), s.nextInt()));
            num--;
        }
        for( Student t : students) {
            System.out.println(t);
        }
    }
}

class Student {
    private final String name;
    private final int math;
    private final int english;
    private final int chinese;

    public String getName() {
        return name;
    }

    public int getMath() {
        return math;
    }

    public int getEnglish() {
        return english;
    }

    public int getChinese() {
        return chinese;
    }
    public int getSum() {
        return math + english + chinese;
    }

    public Student(String name, int math, int english, int chinese) {
        this.name = name;
        this.math = math;
        this.english = english;
        this.chinese = chinese;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", math=" + math +
                ", english=" + english +
                ", chinese=" + chinese +
                '}';
    }
}

### RT-DETRv3 网络结构分析 RT-DETRv3 是一种基于 Transformer 的实时端到端目标检测算法,其核心在于通过引入分层密集正监督方法以及一系列创新性的训练策略,解决了传统 DETR 模型收敛慢和解码器训练不足的问题。以下是 RT-DETRv3 的主要网络结构特点: #### 1. **基于 CNN 的辅助分支** 为了增强编码器的特征表示能力,RT-DETRv3 引入了一个基于卷积神经网络 (CNN) 的辅助分支[^3]。这一分支提供了密集的监督信号,能够与原始解码器协同工作,从而提升整体性能。 ```python class AuxiliaryBranch(nn.Module): def __init__(self, in_channels, out_channels): super(AuxiliaryBranch, self).__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) self.bn = nn.BatchNorm2d(out_channels) def forward(self, x): return F.relu(self.bn(self.conv(x))) ``` 此部分的设计灵感来源于传统的 CNN 架构,例如 YOLO 系列中的 CSPNet 和 PAN 结构[^2],这些技术被用来优化特征提取效率并减少计算开销。 --- #### 2. **自注意力扰动学习策略** 为解决解码器训练不足的问题,RT-DETRv3 提出了一种名为 *self-att 扰动* 的新学习策略。这种策略通过对多个查询组中阳性样本的标签分配进行多样化处理,有效增加了阳例的数量,进而提高了模型的学习能力和泛化性能。 具体实现方式是在训练过程中动态调整注意力权重分布,确保更多的高质量查询可以与真实标注 (Ground Truth) 进行匹配。 --- #### 3. **共享权重解编码器分支** 除了上述改进外,RT-DETRv3 还引入了一个共享权重的解编码器分支,专门用于提供密集的正向监督信号。这一设计不仅简化了模型架构,还显著降低了参数量和推理时间,使其更适合实时应用需求。 ```python class SharedDecoderEncoder(nn.Module): def __init__(self, d_model, nhead, num_layers): super(SharedDecoderEncoder, self).__init__() decoder_layer = nn.TransformerDecoderLayer(d_model=d_model, nhead=nhead) self.decoder = nn.TransformerDecoder(decoder_layer, num_layers=num_layers) def forward(self, tgt, memory): return self.decoder(tgt=tgt, memory=memory) ``` 通过这种方式,RT-DETRv3 实现了高效的目标检测流程,在保持高精度的同时大幅缩短了推理延迟。 --- #### 4. **与其他模型的关系** 值得一提的是,RT-DETRv3 并未完全抛弃经典的 CNN 技术,而是将其与 Transformer 结合起来形成混合架构[^4]。例如,它采用了 YOLO 系列中的 RepNCSP 模块替代冗余的多尺度自注意力层,从而减少了不必要的计算负担。 此外,RT-DETRv3 还借鉴了 DETR 的一对一匹配策略,并在此基础上进行了优化,进一步提升了小目标检测的能力。 --- ### 总结 综上所述,RT-DETRv3 的网络结构主要包括以下几个关键组件:基于 CNN 的辅助分支、自注意力扰动学习策略、共享权重解编码器分支以及混合编码器设计。这些技术创新共同推动了实时目标检测领域的发展,使其在复杂场景下的表现更加出色。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值