贪心算法应用:装箱问题(FFD问题)详解
贪心算法应用:装箱问题(FFD问题)详解
1. 装箱问题概述
装箱问题(Bin Packing Problem)是计算机科学和运筹学中的一个经典组合优化问题。问题的描述如下:
给定一组物品,每个物品有一定的体积,以及若干容量相同的箱子,目标是用最少数量的箱子装下所有物品。
问题形式化描述
- 输入:
- n个物品,每个物品有一个大小wᵢ,其中0 < wᵢ ≤ C(C为箱子容量)
- 无限数量的箱子,每个箱子容量为C
- 输出:
- 将n个物品分配到尽可能少的箱子中,且每个箱子中物品大小之和不超过C
2. 贪心算法简介
贪心算法(Greedy Algorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。
对于装箱问题,常见的贪心算法策略有:
- 首次适应算法(First Fit, FF):将每个物品放入第一个能容纳它的箱子
- 最佳适应算法(Best Fit, BF):将每个物品放入能容纳它的最满的箱子
- 首次适应递减算法(First Fit Decreasing, FFD):先将物品按大小降序排序,然后使用首次适应算法
- 最佳适应递减算法(Best Fit Decreasing, BFD):先将物品按大小降序排序,然后使用最佳适应算法
本文将重点介绍**首次适应递减算法(FFD)**及其Java实现。
3. 首次适应递减算法(FFD)详解
3.1 算法思想
FFD算法是解决装箱问题最常用的启发式算法之一,其基本思想是:
- 先将所有物品按体积从大到小排序
- 然后依次处理每个物品,将其放入第一个能容纳它的箱子
- 如果没有合适的箱子,则开启一个新箱子
3.2 算法步骤
- 输入物品列表和箱子容量C
- 将物品按体积从大到小排序
- 初始化空的箱子列表
- 对于每个物品:
a. 遍历已有箱子,找到第一个能容纳该物品的箱子
b. 如果找到,将物品放入该箱子
c. 如果没有找到,创建一个新箱子并将物品放入 - 返回使用的箱子列表
3.3 算法复杂度分析
- 排序阶段:O(n log n),取决于排序算法
- 装箱阶段:最坏情况下为O(n²),因为对于每个物品可能需要遍历所有箱子
3.4 算法性能
FFD算法有以下性能保证:
- 对于任何输入,FFD使用的箱子数不超过(11/9)*OPT + 1,其中OPT是最优解
- 对于大多数实际案例,FFD的表现非常接近最优解
4. Java实现FFD算法
4.1 基本实现
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class BinPackingFFD {public static void main(String[] args) {// 示例物品大小List<Integer> items = List.of(4, 8, 5, 1, 2, 3, 6, 7, 9, 4);int binCapacity = 10;List<List<Integer>> bins = firstFitDecreasing(items, binCapacity);System.out.println("使用的箱子数量: " + bins.size());for (int i = 0; i < bins.size(); i++) {System.out.println("箱子 " + (i+1) + ": " + bins.get(i) + " (总大小: " + bins.get(i).stream().mapToInt(Integer::intValue).sum() + ")");}}public static List<List<Integer>> firstFitDecreasing(List<Integer> items, int binCapacity) {// 复制物品列表以避免修改原始数据List<Integer> sortedItems = new ArrayList<>(items);// 按降序排序sortedItems.sort(Collections.reverseOrder());List<List<Integer>> bins = new ArrayList<>();for (int item : sortedItems) {boolean placed = false;// 尝试将物品放入已有箱子for (List<Integer> bin : bins) {int currentBinWeight = bin.stream().mapToInt(Integer::intValue).sum();if (currentBinWeight + item <= binCapacity) {bin.add(item);placed = true;break;}}// 如果没有合适的箱子,创建新箱子if (!placed) {List<Integer> newBin = new ArrayList<>();newBin.add(item);bins.add(newBin);}}return bins;}
}
4.2 优化实现
为了提高效率,我们可以预先计算并存储每个箱子的剩余容量:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class BinPackingFFDOptimized {public static void main(String[] args) {List<Integer> items = List.of(4, 8, 5, 1, 2, 3, 6, 7, 9, 4);int binCapacity = 10;List<Bin> bins = firstFitDecreasingOptimized(items, binCapacity);System.out.println("使用的箱子数量: " + bins.size());for (int i = 0; i < bins.size(); i++) {System.out.println("箱子 " + (i+1) + ": " + bins.get(i).items + " (总大小: " + bins.get(i).currentWeight + ")");}}static class Bin {List<Integer> items = new ArrayList<>();int currentWeight = 0;int capacity;Bin(int capacity) {this.capacity = capacity;}boolean canAdd(int item) {return currentWeight + item <= capacity;}void addItem(int item) {items.add(item);currentWeight += item;}}public static List<Bin> firstFitDecreasingOptimized(List<Integer> items, int binCapacity) {List<Integer> sortedItems = new ArrayList<>(items);sortedItems.sort(Collections.reverseOrder());List<Bin> bins = new ArrayList<>();for (int item : sortedItems) {boolean placed = false;for (Bin bin : bins) {if (bin.canAdd(item)) {bin.addItem(item);placed = true;break;}}if (!placed) {Bin newBin = new Bin(binCapacity);newBin.addItem(item);bins.add(newBin);}}return bins;}
}
4.3 进一步优化:使用优先队列
我们可以使用优先队列来更高效地找到合适的箱子:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.PriorityQueue;public class BinPackingFFDWithPQ {public static void main(String[] args) {List<Integer> items = List.of(4, 8, 5, 1, 2, 3, 6, 7, 9, 4);int binCapacity = 10;List<Bin> bins = firstFitDecreasingWithPQ(items, binCapacity);System.out.println("使用的箱子数量: " + bins.size());for (int i = 0; i < bins.size(); i++) {System.out.println("箱子 " + (i+1) + ": " + bins.get(i).items + " (总大小: " + bins.get(i).currentWeight + ")");}}static class Bin implements Comparable<Bin> {List<Integer> items = new ArrayList<>();int currentWeight = 0;int capacity;Bin(int capacity) {this.capacity = capacity;}boolean canAdd(int item) {return currentWeight + item <= capacity;}void addItem(int item) {items.add(item);currentWeight += item;}// 按照剩余容量升序排列,这样我们可以优先尝试剩余容量多的箱子@Overridepublic int compareTo(Bin other) {return Integer.compare(other.capacity - other.currentWeight, this.capacity - this.currentWeight);}}public static List<Bin> firstFitDecreasingWithPQ(List<Integer> items, int binCapacity) {List<Integer> sortedItems = new ArrayList<>(items);sortedItems.sort(Collections.reverseOrder());List<Bin> bins = new ArrayList<>();PriorityQueue<Bin> pq = new PriorityQueue<>();for (int item : sortedItems) {Bin bin = pq.peek();if (bin != null && bin.canAdd(item)) {bin = pq.poll();bin.addItem(item);pq.offer(bin);} else {Bin newBin = new Bin(binCapacity);newBin.addItem(item);bins.add(newBin);pq.offer(newBin);}}return bins;}
}
5. 算法测试与验证
5.1 测试用例设计
为了验证我们的实现是否正确,我们可以设计以下测试用例:
-
简单测试:少量物品,容易验证
- 输入:[2, 3, 4, 5], 容量=7
- 预期:2个箱子 [5,2]和[4,3]
-
边界测试:
- 所有物品大小相同
- 单个物品正好装满一个箱子
- 单个物品超过箱子容量(应抛出异常)
-
随机测试:
- 生成随机物品列表进行测试
-
已知最优解测试:
- 使用已知最优解的小规模问题
5.2 测试代码实现
import org.junit.Test;
import static org.junit.Assert.*;
import java.util.List;public class BinPackingFFDTest {@Testpublic void testSimpleCase() {List<Integer> items = List.of(2, 3, 4, 5);int binCapacity = 7;List<List<Integer>> bins = BinPackingFFD.firstFitDecreasing(items, binCapacity);assertEquals(2, bins.size());assertTrue(bins.get(0).containsAll(List.of(5, 2)) || bins.get(1).containsAll(List.of(5, 2)));assertTrue(bins.get(0).containsAll(List.of(4, 3)) || bins.get(1).containsAll(List.of(4, 3)));}@Testpublic void testPerfectFit() {List<Integer> items = List.of(5, 5, 5, 5);int binCapacity = 10;List<List<Integer>> bins = BinPackingFFD.firstFitDecreasing(items, binCapacity);assertEquals(2, bins.size());for (List<Integer> bin : bins) {assertEquals(10, bin.stream().mapToInt(Integer::intValue).sum());}}@Testpublic void testSingleItem() {List<Integer> items = List.of(7);int binCapacity = 10;List<List<Integer>> bins = BinPackingFFD.firstFitDecreasing(items, binCapacity);assertEquals(1, bins.size());assertEquals(7, bins.get(0).stream().mapToInt(Integer::intValue).sum());}@Test(expected = IllegalArgumentException.class)public void testItemTooLarge() {List<Integer> items = List.of(11);int binCapacity = 10;BinPackingFFD.firstFitDecreasing(items, binCapacity);}@Testpublic void testEmptyInput() {List<Integer> items = List.of();int binCapacity = 10;List<List<Integer>> bins = BinPackingFFD.firstFitDecreasing(items, binCapacity);assertTrue(bins.isEmpty());}
}
6. 性能分析与优化
6.1 时间复杂度分析
- 排序阶段:O(n log n)
- 装箱阶段:
- 基本实现:O(n²) - 对于每个物品,最坏情况下需要检查所有箱子
- 优先队列优化:O(n log n) - 每次插入和提取操作都是O(log n)
6.2 空间复杂度分析
- O(n) - 需要存储所有物品和箱子信息
6.3 实际性能测试
我们可以编写性能测试代码来比较不同实现的性能:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;public class BinPackingPerformanceTest {public static void main(String[] args) {int numItems = 10000;int binCapacity = 100;List<Integer> items = generateRandomItems(numItems, binCapacity);// 预热firstFitDecreasing(new ArrayList<>(items), binCapacity);firstFitDecreasingOptimized(new ArrayList<>(items), binCapacity);firstFitDecreasingWithPQ(new ArrayList<>(items), binCapacity);// 测试基本实现long start = System.currentTimeMillis();List<List<Integer>> bins1 = firstFitDecreasing(new ArrayList<>(items), binCapacity);long end = System.currentTimeMillis();System.out.println("基本实现: " + (end - start) + "ms, 箱子数: " + bins1.size());// 测试优化实现start = System.currentTimeMillis();List<BinPackingFFDOptimized.Bin> bins2 = firstFitDecreasingOptimized(new ArrayList<>(items), binCapacity);end = System.currentTimeMillis();System.out.println("优化实现: " + (end - start) + "ms, 箱子数: " + bins2.size());// 测试优先队列实现start = System.currentTimeMillis();List<BinPackingFFDWithPQ.Bin> bins3 = firstFitDecreasingWithPQ(new ArrayList<>(items), binCapacity);end = System.currentTimeMillis();System.out.println("优先队列实现: " + (end - start) + "ms, 箱子数: " + bins3.size());}private static List<Integer> generateRandomItems(int numItems, int maxSize) {List<Integer> items = new ArrayList<>();Random random = new Random();for (int i = 0; i < numItems; i++) {items.add(random.nextInt(maxSize) + 1); // 1到maxSize}return items;}// 这里需要包含前面三个实现的方法...
}
7. 应用场景与扩展
7.1 实际应用场景
装箱问题在现实世界中有许多应用:
- 物流与运输:将货物装入集装箱或卡车
- 资源分配:云计算中的虚拟机分配
- 存储管理:文件存储到磁盘或内存中
- 生产计划:任务分配到机器上
- 广告投放:将广告分配到固定时长的广告位
7.2 变种与扩展
- 多维装箱问题:物品有多个维度(长、宽、高)
- 可变大小箱子:箱子大小可以不同
- 成本最小化:不同箱子有不同的成本
- 在线装箱问题:物品按顺序到达,必须立即分配
- 带冲突的装箱问题:某些物品不能放在同一个箱子中
7.3 其他算法比较
虽然FFD是一个很好的启发式算法,但还有其他算法可以解决装箱问题:
-
精确算法:
- 分支限界法
- 动态规划(适用于小规模问题)
-
近似算法:
- Next Fit (NF)
- Worst Fit (WF)
- Almost Worst Fit (AWF)
-
元启发式算法(适用于大规模问题):
- 遗传算法
- 模拟退火
- 禁忌搜索
8. 完整Java实现示例
以下是结合了所有优化和功能的完整实现:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.PriorityQueue;public class AdvancedBinPackingFFD {public static void main(String[] args) {// 示例使用List<Integer> items = generateRandomItems(20, 10);int binCapacity = 10;System.out.println("物品列表: " + items);BinPackingResult result = packItems(items, binCapacity);System.out.println("使用的箱子数量: " + result.getBinCount());System.out.println("平均填充率: " + String.format("%.2f", result.getAverageFillRate() * 100) + "%");System.out.println("详细装箱情况:");result.printBins();}/*** 装箱结果类*/public static class BinPackingResult {private final List<Bin> bins;private final int binCapacity;public BinPackingResult(List<Bin> bins, int binCapacity) {this.bins = bins;this.binCapacity = binCapacity;}public int getBinCount() {return bins.size();}public double getAverageFillRate() {return bins.stream().mapToDouble(bin -> (double)bin.getCurrentWeight() / binCapacity).average().orElse(0);}public void printBins() {for (int i = 0; i < bins.size(); i++) {Bin bin = bins.get(i);System.out.printf("箱子 %2d: %s (总大小: %2d, 填充率: %5.2f%%)%n",i + 1, bin.getItems(), bin.getCurrentWeight(),(double)bin.getCurrentWeight() / binCapacity * 100);}}public List<Bin> getBins() {return Collections.unmodifiableList(bins);}}/*** 箱子类*/public static class Bin implements Comparable<Bin> {private final List<Integer> items = new ArrayList<>();private int currentWeight = 0;private final int capacity;public Bin(int capacity) {this.capacity = capacity;}public boolean canAdd(int item) {if (item > capacity) {throw new IllegalArgumentException("物品大小超过箱子容量");}return currentWeight + item <= capacity;}public void addItem(int item) {if (!canAdd(item)) {throw new IllegalStateException("无法将物品添加到箱子中");}items.add(item);currentWeight += item;}public List<Integer> getItems() {return Collections.unmodifiableList(items);}public int getCurrentWeight() {return currentWeight;}public int getRemainingCapacity() {return capacity - currentWeight;}@Overridepublic int compareTo(Bin other) {// 按剩余容量降序排列return Integer.compare(other.getRemainingCapacity(), this.getRemainingCapacity());}}/*** 装箱方法*/public static BinPackingResult packItems(List<Integer> items, int binCapacity) {// 验证输入if (binCapacity <= 0) {throw new IllegalArgumentException("箱子容量必须为正数");}for (int item : items) {if (item <= 0) {throw new IllegalArgumentException("物品大小必须为正数");}if (item > binCapacity) {throw new IllegalArgumentException("存在物品大小超过箱子容量");}}// 复制物品列表以避免修改原始数据List<Integer> sortedItems = new ArrayList<>(items);// 按降序排序sortedItems.sort(Collections.reverseOrder());List<Bin> bins = new ArrayList<>();PriorityQueue<Bin> binQueue = new PriorityQueue<>();for (int item : sortedItems) {Bin bin = binQueue.peek();if (bin != null && bin.canAdd(item)) {bin = binQueue.poll();bin.addItem(item);binQueue.offer(bin);} else {Bin newBin = new Bin(binCapacity);newBin.addItem(item);bins.add(newBin);binQueue.offer(newBin);}}return new BinPackingResult(bins, binCapacity);}/*** 生成随机物品列表*/public static List<Integer> generateRandomItems(int count, int maxSize) {List<Integer> items = new ArrayList<>();java.util.Random random = new java.util.Random();for (int i = 0; i < count; i++) {items.add(random.nextInt(maxSize) + 1); // 1到maxSize}return items;}
}
9. 总结
首次适应递减算法(FFD)是解决装箱问题的一种高效启发式算法,通过先将物品按大小降序排序,然后使用首次适应策略,能够在大多数情况下得到接近最优的解。本文详细介绍了:
- 装箱问题的定义和贪心算法的基本概念
- FFD算法的详细思想和实现步骤
- 多种Java实现方式,包括基本实现、优化实现和使用优先队列的实现
- 测试用例设计和性能分析方法
- 实际应用场景和算法扩展
FFD算法的时间复杂度主要取决于排序阶段(O(n log n))和装箱阶段(O(n²)或优化后的O(n log n)),在实际应用中表现良好。对于需要更高精度的场景,可以考虑结合其他优化算法或精确算法。
更多资源:
https://www.kdocs.cn/l/cvk0eoGYucWA
本文发表于【纪元A梦】!
相关文章:

贪心算法应用:装箱问题(FFD问题)详解
贪心算法应用:装箱问题(FFD问题)详解 1. 装箱问题概述 装箱问题(Bin Packing Problem)是计算机科学和运筹学中的一个经典组合优化问题。问题的描述如下: 给定一组物品,每个物品有一定的体积,以及若干容量相同的箱子,…...
机器学习的数学基础:假设检验
假设检验 默认以错误率为性能度量,错误率由下式给出: E ( f , D ) ∫ x ∼ D I I ( f ( x ) ≠ y ) p ( x ) d x E(f,\mathcal{D})\int_{\boldsymbol{x}\sim \mathcal{D}}\mathbb{II}(f(\boldsymbol{x})\ne y )p(\boldsymbol{x})\text{d}\boldsymbol{x…...
余氯传感器在智慧水务系统中如何实现IoT集成
现代余氯传感器(关键词:智能余氯监测、物联网水质传感器、LoRaWAN水监测)通过(关键词:Modbus RTU、4-20mA输出、NB-IoT传输)协议与SCADA系统对接,实现(关键词:远程氯浓度…...

操作系统学习(九)——存储系统
一、存储系统 在操作系统中,存储系统(Storage System) 是计算机系统的核心组成部分之一,它负责数据的存储、组织、管理和访问。 它不仅包括物理设备(如内存、硬盘),还包括操作系统提供的逻辑抽…...

服务器安装软件失败或缺依赖怎么办?
服务器在安装软件时失败或提示缺少依赖,是运维中非常常见的问题。这个问题大多发生在 Linux 云服务器环境,原因和解决方法也有共性。以下是详细说明和解决建议: 🧠 一、常见原因分析 问题类型描述🔌 软件源不可用服务器…...
linux nm/objdump/readelf/addr2line命令详解
我们在开发过程中通过需要反汇编查看问题,那么我们这里使用rk3568开发板来举例nm/objdump/readelf/addr2line 分析动态库和可执行文件以及.o文件。 1,我们举例nm/objdump/readelf/addr2line解析linux 内核文件vmlinux (1),addr2…...

006网上订餐系统技术解析:打造高效便捷的餐饮服务平台
网上订餐系统技术解析:打造高效便捷的餐饮服务平台 在数字化生活方式普及的当下,网上订餐系统成为连接餐饮商家与消费者的重要桥梁。该系统以菜品分类、订单管理等模块为核心,通过前台展示与后台录入的分工协作,为管理员和会员提…...

[10-2]MPU6050简介 江协科技学习笔记(22个知识点)
1 2 3 欧拉角是描述三维空间中刚体或坐标系之间相对旋转的一种方法。它们由三个角度组成,通常表示为: • 偏航角(Yaw):绕垂直轴(通常是z轴)的旋转,表示偏航方向的变化。 • 俯仰角&a…...
基于行为分析的下一代安全防御指南
一、技术原理演进 从特征匹配到行为建模传统防火墙依赖特征库匹配(如病毒指纹),而行为分析技术通过建立用户/设备/应用的正常行为基线(基线构建误差<0.8%),利用隐马尔可夫模型检测异常。微软Az…...
Redis持久化机制详解:RDB与AOF的深度剖析
一、为什么需要持久化? Redis作为内存数据库,数据存储在易失性内存中。持久化机制解决两大核心问题: 数据安全:防止服务器宕机导致数据丢失灾难恢复:支持数据备份与快速重建 二、RDB:内存快照持久化 ▶ …...
记录一次 apt-key curl导入失败的处理方式
在配置 Kubernetes APT 仓库的过程中,我们通常会执行如下命令来添加阿里云的 GPG 公钥: curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -但这次在某台新机器上执行时,出现了访问失败的问题。具体表现为 cu…...

Spring Boot 3.X 下Redis缓存的尝试(二):自动注解实现自动化缓存操作
前言 上文我们做了在Spring Boot下对Redis的基本操作,如果频繁对Redis进行操作而写对应的方法显示使用注释更会更高效; 比如: 依之前操作对一个业务进行定入缓存需要把数据拉取到后再定入; 而今天我们可以通过注释的方式不需要额外…...

【03】完整开发腾讯云播放器SDK的UniApp官方UTS插件——优雅草上架插件市场-卓伊凡
【03】完整开发腾讯云播放器SDK的UniApp官方UTS插件——优雅草上架插件市场-卓伊凡 一、项目背景与转型原因 1.1 原定计划的变更 本系列教程最初规划是开发即构美颜SDK的UTS插件,但由于甲方公司内部战略调整,原项目被迫中止。考虑到: 技术…...

C:\Users\中文名修改为英文名
C:\Users\中文名修改为英文名 背景操作步骤 背景 买了台新电脑,初始化好不知道啥操作把自己的登录用户名改成了中文,有些安装的软件看见有中文直接就水土不服了。 操作步骤 以下称中文用户名为张三。 正常登录张三用户 进入用户管理页面修改用户名&a…...
Web 架构相关文章目录(持续更新中)
文章目录 目录结构总结 目录结构 序号标题链接1Web 架构之数据库开发规范Web 架构之数据库开发规范2Web 架构之状态码全解Web 架构之状态码全解3Web 架构之会话保持深度解析Web 架构之会话保持深度解析4Web 架构之负载均衡会话保持Web 架构之负载均衡会话保持5Web 架构之攻击应…...
Redis 安装配置和性能优化
目录 简介 一、Redis 基础概念与优势 1.1 关系型与非关系型数据库对比 1.2 Redis 核心特性 二、Redis 部署 2.1 环境准备与源码安装 2.2 服务脚本配置与启动 三、Redis 配置参数 四、Redis 命令工具与常用操作 4.1 命令行工具(redis-cli) 4.2…...

购物商城网站 Java+Vue.js+SpringBoot,包括商家管理、商品分类管理、商品管理、在线客服管理、购物订单模块
购物商城网站 JavaVue.jsSpringBoot,包括商家管理、商品分类管理、商品管理、在线客服管理、购物订单模块 百度云盘链接:https://pan.baidu.com/s/10W0kpwswDSmtbqYFsQmm5w 密码:68jy 摘 要 随着科学技术的飞速发展,各行各业都在…...
PostgreSQL 安全纵深防御:从权限到加密
文章目录 PostgreSQL 安全纵深防御:从权限到加密 第一章:角色与权限体系 - PostgreSQL的安全基石 1.1 角色(ROLE)的本质与演进1.2 权限模型的三层架构1.3 GRANT/REVOKE 实战精解1.4 默认权限(DEFAULT PRIVILEGES&#…...
【美团技术团队】从实际案例聊聊Java应用的GC优化
【美团技术团队】从实际案例聊聊Java应用的GC优化 1. 美团技术团队优秀文章2. 绪论 1. 美团技术团队优秀文章 Java NIO浅析 https://tech.meituan.com/2016/11/04/nio.html红黑树深入剖析及Java实现 https://tech.meituan.com/2016/12/02/redblack-tree.htmlJava 8系列之重新认…...

在word中点击zotero Add/Edit Citation没有反应的解决办法
重新安装了word插件 1.关掉word 2.进入Zotero左上角编辑-引用 3.往下滑找到Microsoft Word,点重新安装加载项...

整合swagger,以及Knife4j优化界面
因为是前后端项目,需要前端的参与,所以一个好看的接口文档非常的重要 1、引入依赖 美化插件其中自带swagger的依赖了 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-spring-boot-starter&…...

Unity | AmplifyShaderEditor插件基础(第四集:简易shader)
一、👋🏻前言 大家好,我是菌菌巧乐兹~本节内容主要讲一下,第一个用ASE的shader。 我们用通用的光照模版吧。(universal-通用/Lit-光照) 通用的光照模版 如果你尝试建设了,会发现Universal这个…...
【安全攻防与漏洞】量子计算对HTTPS的威胁:后量子密码学进展
⚛️ 一、量子计算对HTTPS的核心威胁 Shor算法破解非对称加密 Shor算法可高效分解大整数(破解RSA)和计算椭圆曲线离散对数(破解ECC),而HTTPS依赖的TLS握手阶段依赖RSA/ECC进行密钥交换和身份验证。一旦实用化量子计算…...

linux C语言中的动态库 静态库说明
静态库 gcc -fpic -c add.c sub.c 这个命令之后会得到 add.o 于 sub.o (-c 只编译不链接) ar rcs mymath.a add.o sub.o 将编译好的文件编译成.a静态库用于调用 在使用中 gcc main.c -I../include ../lib/mymarh.a -0 mytest 需要这个函数的声明放在include文件下…...

Flash烧录速度和加载配置速度(纯FPGA ZYNQ)
在工程综合完成或者implement完成后,打开综合设计或者实现设计。 toots--->Edit Device Properties--->打开比特流设置 将bitstream进行压缩 上图中,时钟频率选择的档位有限,最大为66MHZ io的bus width可以设置为x1,x2,x4 vivado在设计…...

解构与重构:PLM 系统如何从管理工具进化为创新操作系统?
在智能汽车、工业物联网等新兴领域的冲击下,传统产品生命周期管理(PLM)系统正在经历前所未有的范式转换。当某头部车企因 ECU 软件与硬件模具版本失配导致 10 万辆智能电车召回,损失高达 6 亿美元时,这场危机不仅暴露了…...

Redis:介绍和认识,通用命令,数据类型和内部编码,单线程模型
介绍和认识 Redis是一个基于内存的,高性能的,支持许多数据类型的NoSQL数据库,可以持久化,也支持分布式。 在许多的互联网产品中,对于数据库的访问速度要求很高,例如Mysql数据库无法满足其要求,…...
N2语法 強調、限定
1,~限りでは 接続:认知类动词 意味:据…所… 例文: 私の知る限りでは、彼は悪い人ではありません。(据我所知,他不是坏人) 私の調べた限りでは、彼は悪人では…...
OpenAI 即将推出 GPT-5:开启多模态、持续记忆对话新时代
2025年5月起,关于 OpenAI 新一代旗舰模型 GPT-5 的传闻不断升温。根据多方可信消息,OpenAI 正在积极准备 GPT-5 的正式发布,预计将在 2025 年夏末上线。这一代模型不仅是在规模上的升级,更是在能力与交互模式上的一次突破。 本文…...
《前端面试题:CSS预处理器(Sass、Less等)》
CSS预处理器深度解析:Sass与Less的全面指南 掌握CSS预处理器是现代前端开发的必备技能,也是提升开发效率的关键工具 一、为什么需要CSS预处理器? 在现代前端开发中,原生CSS的局限性日益明显: 缺乏编程特性࿰…...