三十八、动态规划——背包问题( 01 背包 + 完全背包 + 多重背包 + 分组背包 + 优化)

news2024/11/25 21:12:13

动态规划-背包问题算法主要内容

  • 一、基本思路
    • 1、背包问题概述
    • 2、动态规划(DP)问题分析
  • 二、背包问题
    • 1、0 1 背包问题
    • 2、完全背包问题
    • 3、多重背包问题
    • 4、分组背包问题
  • 三、例题题解

一、基本思路

1、背包问题概述

  • 0 1 背包问题:
    • 条件:N 个物品容量为 V 的背包,每件物品最多用 1 次,其中物品信息体积为 Vi,价值为 Wi。
    • 目标:选出物品,使价值最大(不一定装满背包)。
    • 特点:每件物品最多只用 1 次
  • 完全背包问题:
    • 特点:每一件物品都有无限个
  • 多重背包问题:
    • 特点:每个物品有 si 个(有限个)
    • 优化:当面对物品种类比较多的时候,复杂度较高,可以进行优化操作;DP优化一般是对动态规划的方程和代码做等价变形。
  • 分组背包问题:
    • 特点:有 N 组物品,每一组物品里面有 si 种物品,一组里面只能选择 1 个物品

2、动态规划(DP)问题分析

  • 分析步骤:
    *
  • 背包问题中的状态表示 f [ i , j ]:
    • f [ N, V ] 表示所有从前 N 个物品中选,且总体积不超过 V 的选法集合, f [N, V]表示集合中每种选法总价值的最大值。

二、背包问题

1、0 1 背包问题

  • 集合划分:

在这里插入图片描述

  • 一维优化:
  • 将 f 的第一个维度优化掉,但是需要注意是否使用到 f [ i - 1 ][] 也就是前面一层的数值,使用到的话就需要进行倒序遍历,否则会发生更新。

在这里插入图片描述

// 因为左边的j是由右边的j更新过来的,所以替换成一维还是用的上一层i-1的j
// f[j] = f[j]; // 左边不包含i的方案
// f[i][j] = f[i-1][j]; 
// f[i][j] = Math.max(f[i][j], f[i - 1][j - v[i]] + w[i]);  
// 因为我们的f[i][j]是由f[i - 1][j]更新过来的,
// 替换成一维之后,需要保证f[j]是由(i - 1)层的f[j - v[i]]更新的
// 又因为(j - v[i]) 严格小于j的,
// 所以f[j - v[i]]肯定是在f[j]之前被求出,我们如果是从小到大枚举的j的话
// 如果有可能枚举到(j - v[i])是在我们当前 i 层中求出过,那就表示是这一层的值,我们要的是上一层的值
//f[2] = f[2 - 2] = f[0]
//f[3] = f[3 - 2] = f[1]
//f[4] = f[4 - 2] = f[2],这时候的f[2]在我们这一层中更新过,所以用的是我们这一层的值,我们要的是上一层的值

//所以我们需要一共逆序遍历j
//f[9] = f[9 - 3]
//f[8] = f[8 - 3]
//f[7] = f[7 - 3]
//...
//f[3] = f[3 - 3],可以看出没有一个是重复出现的,所以这个时候用的就是上一层的值,《等价变形》
//f[j] = Math.max(f[j] , f[j - v[i]] + w[i]);   //右边包含i的方案,f[i-1][j - v[i]] + w[i]

2、完全背包问题

  • 思路分析:
    在这里插入图片描述

  • 集合划分:
    在这里插入图片描述

  • 思路优化:

在这里插入图片描述

3、多重背包问题

  • 思路分析:

在这里插入图片描述

  • 集合划分:
  • 此处是暴力做法,对于物品 0 < NV ≤ 100 ,0 < vi,wi,si ≤ 100 满足,假如数据表达则复杂度较高。
    在这里插入图片描述
  • 思路优化——二进制优化:
  • 主要思想是将 si 进行分解,使用二进制进行表示。
  • 注意此种方法主要是处理 物品种类 N 数值较大,导致的的计算复杂度较大的问题。

在这里插入图片描述
在这里插入图片描述

4、分组背包问题

  • 思路分析:

在这里插入图片描述

  • 集合划分:

在这里插入图片描述

三、例题题解

在这里插入图片描述

// java题解实现

// f[i][j] 方阵形式————朴素形式
// 将所要求的属性,进行集合划分

import java.util.*;
import java.io.*;

public class Main{
    static int N = 1010;
    static int[] v = new int[N];        // 每件物品体积
    static int[] w = new int[N];        // 每件物品价值
    static int[][] f = new int[N][N];

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        int n,m;                // n为件数,m为背包体积

        String[] str1 = in.readLine().split(" ");
        n = Integer.parseInt(str1[0]);
        m = Integer.parseInt(str1[1]);

        for(int i = 1; i <= n; i++){
            String[] str2 = in.readLine().split(" ");
            v[i] = Integer.parseInt(str2[0]);
            w[i] = Integer.parseInt(str2[1]);
        }

        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                f[i][j] = f[i - 1][j];      // 不含有第i件物品的最大价值
                if(j >= v[i]){              // 判断是否能加入背包,如果物品体积比背包大,那就加入不了
                    f[i][j] = Math.max(f[i][j], f[i - 1][j - v[i]] + w[i]);         
                    // 含有第i件物品的最大价值,求解max
                    // 求解最大的时候暗含一个逻辑,就是之前没加vi已经能存多少了,和加了vi(有可能只剩下i)进行比较
                    // 看看哪一个多,是多个小件总价值大,还是一个大件价值大
                }
            }
        }

        System.out.println(f[n][m]);
    }

}
// 一维优化做法
import java.util.*;
import java.io.*;

public class Main{
    static int N = 1010;
    static int[] v = new int[N];        // 每件物品体积
    static int[] w = new int[N];        // 每件物品价值
    static int[] f = new int[N];

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        int n,m;                // n为件数,m为背包体积

        String[] str1 = in.readLine().split(" ");
        n = Integer.parseInt(str1[0]);
        m = Integer.parseInt(str1[1]);

        for(int i = 1; i <= n; i++){
            String[] str2 = in.readLine().split(" ");
            v[i] = Integer.parseInt(str2[0]);
            w[i] = Integer.parseInt(str2[1]);
        }

        for(int i = 1; i <= n; i++){
            for(int j = m; j >= v[i]; j--){

                    f[j] = Math.max(f[j], f[j - v[i]] + w[i]);         

                //因为左边的j是由右边的j更新过来的,所以替换成一维还是用的上一层i-1的j
                //f[j] = f[j]; // 左边不包含i的方案
                //f[i][j] = f[i-1][j]; 
                // f[i][j] = Math.max(f[i][j], f[i - 1][j - v[i]] + w[i]);  
                //因为我们的f[i][j]是由f[i - 1][j]更新过来的,
                //替换成一维之后,需要保证f[j]是由(i - 1)层的f[j - v[i]]更新的
                //又因为(j - v[i]) 严格小于j的,
                //所以f[j - v[i]]肯定是在f[j]之前被求出,我们如果是从小到大枚举的j的话
                //如果有可能枚举到(j - v[i])是在我们当前 i 层中求出过,那就表示是这一层的值,我们要的是上一层的值
                //f[2] = f[2 - 2] = f[0]
                //f[3] = f[3 - 2] = f[1]
                //f[4] = f[4 - 2] = f[2],这时候的f[2]在我们这一层中更新过,所以用的是我们这一层的值,我们要的是上一层的值

                //所以我们需要一共逆序遍历j
                //f[9] = f[9 - 3]
                //f[8] = f[8 - 3]
                //f[7] = f[7 - 3]
                //...
                //f[3] = f[3 - 3],可以看出没有一个是重复出现的,所以这个时候用的就是上一层的值,《等价变形》
                //f[j] = Math.max(f[j] , f[j - v[i]] + w[i]);   //右边包含i的方案,f[i-1][j - v[i]] + w[i]


            }
        }

        System.out.println(f[m]);
    }

}

在这里插入图片描述

// 完全背包问题
// 朴素算法

import java.util.*;
import java.io.*;

public class Main{
    static int N = 1010;
    static int[] v = new int[N];        // 每件物品体积
    static int[] w = new int[N];        // 每件物品价值
    static int[][] f = new int[N][N];

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        int n,m;                // n为件数,m为背包体积

        String[] str1 = in.readLine().split(" ");
        n = Integer.parseInt(str1[0]);
        m = Integer.parseInt(str1[1]);

        for(int i = 1; i <= n; i++){
            String[] str2 = in.readLine().split(" ");
            v[i] = Integer.parseInt(str2[0]);
            w[i] = Integer.parseInt(str2[1]);
        }


        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                for(int k = 0; k * v[i] <= j; k++){     // 选择 k 个第 i 个物品
                    f[i][j] = Math.max(f[i][j], f[i - 1][j - v[i]*k] + w[i] * k);
                }
            }
        }


        System.out.println(f[n][m]);
    }

}

// 完全背包问题
// 进一步推导的结果

import java.util.*;
import java.io.*;

public class Main{
    static int N = 1010;
    static int[] v = new int[N];        // 每件物品体积
    static int[] w = new int[N];        // 每件物品价值
    static int[][] f = new int[N][N];

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        int n,m;                // n为件数,m为背包体积

        String[] str1 = in.readLine().split(" ");
        n = Integer.parseInt(str1[0]);
        m = Integer.parseInt(str1[1]);

        for(int i = 1; i <= n; i++){
            String[] str2 = in.readLine().split(" ");
            v[i] = Integer.parseInt(str2[0]);
            w[i] = Integer.parseInt(str2[1]);
        }


        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                f[i][j] = f[i- 1][j];
                if(j >= v[i]){
                    f[i][j] = Math.max(f[i][j], f[i][j - v[i]] + w[i]);     // 进一步推导
                }
            }
        }


        System.out.println(f[n][m]);
    }

}

// 完全背包问题
// 一维优化
import java.util.*;
import java.io.*;

public class Main{
    static int N = 1010;
    static int[] v = new int[N];        // 每件物品体积
    static int[] w = new int[N];        // 每件物品价值
    static int[] f = new int[N];

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        int n,m;                // n为件数,m为背包体积

        String[] str1 = in.readLine().split(" ");
        n = Integer.parseInt(str1[0]);
        m = Integer.parseInt(str1[1]);

        for(int i = 1; i <= n; i++){
            String[] str2 = in.readLine().split(" ");
            v[i] = Integer.parseInt(str2[0]);
            w[i] = Integer.parseInt(str2[1]);
        }


        for(int i = 1; i <= n; i++){
            for(int j = v[i]; j <= m; j++){
                    f[j] = Math.max(f[j], f[j - v[i]] + w[i]);
            }
        }


        System.out.println(f[m]);
    }

}

在这里插入图片描述

// 多重背包问题
// 朴素写法

import java.util.*;
import java.io.*;

public class Main{
    static int N = 110;
    static int[] v = new int[N];
    static int[] w = new int[N];
    static int[] s = new int[N];
    static int[][] f = new int[N][N];

    public static void main(String[] args) throws IOException{
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

        int n,m;

        String[] str1 = in.readLine().split(" ");

        n = Integer.parseInt(str1[0]);
        m = Integer.parseInt(str1[1]);

        for(int i = 1; i <= n; i++){
            String[] str2 = in.readLine().split(" ");

            v[i] = Integer.parseInt(str2[0]);
            w[i] = Integer.parseInt(str2[1]);
            s[i] = Integer.parseInt(str2[2]);
        }


        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                for(int k = 0; k <= s[i] && k * v[i] <= j; k++){        // 相对完全背包问题,此处对k增加了限制
                    f[i][j] = Math.max(f[i][j], f[i - 1][j - k * v[i]] + k * w[i]);
                }
            }
        }

        System.out.println(f[n][m]);
    }
}

在这里插入图片描述

// 多重背包问题————二进制优化算法
// 主要思路:
//      1、将N种物品中的每种物品(每种s件),拆分成 N * log(s) 种(将s进行二进制表示尽心拆分)
//      2、对于这N * log(s) 种物品,每种物品只存在选择,还是不选择两种情况,也就意味转化为01背包问题
//  注意:
//      1、进行s拆分的时候,一定也要考虑二进制代表的v、w的会随着二进制数的大小进行翻倍
//      2、s拆分完毕之后,每一种的选择与否由01背包决定
//      3、我们在进行vw存储的时候,每一个都代表了一种s选择方式,但实际上i没有实际意义,只是将s进行拆分后的结果。


import java.util.*;
import java.io.*;

public class Main{
    static int n,m;
    static int N = 12000;
    static int[] v = new int[N];
    static int[] w = new int[N];
    static int[] f = new int[N];

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String[] str1 = in.readLine().split(" ");

        n = Integer.parseInt(str1[0]);
        m = Integer.parseInt(str1[1]);

        int count = 0;          // count是为了记录s拆分为二进制后,新的拆分数量

        for(int i = 1; i <= n; i++){
            String[] str2 = in.readLine().split(" ");

            int vi = Integer.parseInt(str2[0]);
            int wi = Integer.parseInt(str2[1]);
            int si = Integer.parseInt(str2[2]);

            // 将si进行二进制拆分,拆分成logs种新的物品(每种只有一件)
            int k = 1;              // 此处相当于是2的0次幂

            while(si >= k){
                count++;            // 新拆分了一种方法

                v[count] = vi * k;  
                // s在进行拆分二进制的时候,也就对应了此种方法 选择了多少个此种物品作为一个新的物品
                // 那与之对应的vw也就需要更新,作为一种新物品单独看待
                w[count] = wi * k;

                si -= k;         // s 分解成2的0到k次                幂(小于s),
                k *= 2;          // k每次都成2,就是2的倍数
            }

            //比如10,分成 1 2 4 如果加上8加能够凑出1-15个数,所以超过10,所以我们用10减去前面的数,剩下3
            //所以分成 1 2 4 3
            //下面这一步就是判断生下来的数是多少
            if(si > 0){
                count++;
                v[count] = vi * si;     // 此处的si也就是剩下的c,也当做一个新的物品即可
                w[count] = wi * si;
            }

        }

        // 01背包问题解决每种新物品的选择问题
        for(int i = 1; i <= count; i++){                    
        // 拆分s之后每种情况都进行遍历,也就意味着每个si都会根据01背包来确定是否进行重新组合
            for(int j = m; j >= v[i]; j--){
                f[j] = Math.max(f[j], f[j - v[i]] + w[i]);
            }
        }

        System.out.println(f[m]);

    }
}

在这里插入图片描述

import java.util.*;
import java.io.*;

/*
// 一共3组,背包容量为5
3 5

//下面是第一组,一共两件物品
2
//第一件物品的体积为1,价值为2
//第二件物品的体积为2,价值为4
1 2
2 4

//第二组
1
3 4

//第三组
1
4 5
*/


public class Main{
    static int n,m;
    static int N = 110;
    // 此处的ij分别代表的是第i组的第j个物品
    static int[][] v = new int[N][N];
    static int[][] w = new int[N][N];
    static int[] s = new int[N];
    static int[] f = new int[N];

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String[] str1 = in.readLine().split(" ");

        n = Integer.parseInt(str1[0]);
        m = Integer.parseInt(str1[1]);


        for(int i = 1; i <= n; i++){
            String str2 = in.readLine();
            s[i] = Integer.parseInt(str2);

            for(int j = 1; j <= s[i];j ++){
                String[] str3 = in.readLine().split(" ");
                v[i][j]= Integer.parseInt(str3[0]);
                w[i][j] = Integer.parseInt(str3[1]);
            }
        }


        for(int i = 1; i <= n; i++){                    
            for(int j = m; j >= 0; j--){            
                // 因为用到的是f【i-1】【j - v[i][k]】处理,不能对之前的进行更新
                for(int k = 1; k <= s[i]; k++){     // 此处存储的是每组里面的物品数量
                    if(v[i][k] <= j){
                        f[j] = Math.max(f[j], f[j - v[i][k]] + w[i][k]);
                    }
                }
            }
        }

        System.out.println(f[m]);

    }
}

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

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

相关文章

前端解决按钮重复提交数据问题(节流和防抖)

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f35f;欢迎来到前端初见的博文&#xff0c;本文主要讲解在工作解决按钮重复提交数据问题&#xff08;节流和防抖&#xff09; &#x1f468;‍&#x1f527; 个人主页 : 前端初见 &#x1f9…

【redis】数据类型,持久化、事务和锁机制、Java和redis交互、使用redis缓存、三大缓存问题

文章目录 Redis数据库NoSQL概论Redis安装和部署基本操作数据操作 数据类型介绍HashListSet和SortedSet 持久化RDBAOF 事务和锁机制锁 使用Java与Redis交互基本操作SpringBoot整合Redis 使用Redis做缓存Mybatis二级缓存Token持久化存储 三大缓存问题缓存穿透缓存击穿缓存雪崩 Re…

kotlin协程Job、CoroutineScope作用域,Android

kotlin协程Job、CoroutineScope作用域&#xff0c;Android import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines…

(横向刷题)【算法1-6】二分查找与二分答案【算法2-1】前缀和、差分与离散化(上),总结

【算法1-6】二分查找与二分答案 P1024[NOIP2001 提高组] 一元三次方程求解 思路&#xff1a;题目说明根与根之差的绝对值>1,且x1<x2&&f(x1)*f(x2)<0则其中存在解&#xff0c;于是联想到枚举&#xff0c;再用二分答案法控制精度 总结&#xff1a;二分对于精度…

【RabbitMQ教程】第四章 —— RabbitMQ - 交换机

&#x1f4a7; 【 R a b b i t M Q 教程】第四章—— R a b b i t M Q − 交换机 \color{#FF1493}{【RabbitMQ教程】第四章 —— RabbitMQ - 交换机} 【RabbitMQ教程】第四章——RabbitMQ−交换机&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &…

《阿里大数据之路》读书笔记:第一章 总述

阿里巴巴大数据系统体系架构图 阿里数据体系主要分为数据采集、数据计算、数据服务和数据应用四大层次。 一、数据采集层 阿里巴巴建立了一套标准的数据采集体系方案&#xff0c;致力全面、高性能、规范地完成海量数据的采集&#xff0c;并将其传输到大数据平台。 数据来源主…

【C++】 STL(下)算法、迭代器、容器适配器 和 仿函数

文章目录 算法迭代器容器适配器栈&#xff08;stack&#xff09;队列&#xff08;queue&#xff09; 仿函数 算法 STL中的算法头文件位于和文件中&#xff08;以为主&#xff09; for_each(InputIterator First,InputIterator Last,Function _Func); 遍历&#xff0c;具体做什…

电影《天空之城》观后感

上周看了电影《天空之城》这部电影&#xff0c;这部电影是六一儿童节时上映的&#xff0c;本周也算是补票吧&#xff0c;童年时&#xff0c;看的都是免费的&#xff0c;早已经忘记是在哪里看到的&#xff0c;但当时对自己触动很大&#xff0c;算是启蒙电影&#xff0c;所以今天…

【RabbitMQ教程】第二章 —— RabbitMQ - 简单案例

&#x1f4a7; 【 R a b b i t M Q 教程】第二章—— R a b b i t M Q − 简单案例 \color{#FF1493}{【RabbitMQ教程】第二章 —— RabbitMQ - 简单案例} 【RabbitMQ教程】第二章——RabbitMQ−简单案例&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人…

汽车电子Autosar之以太网SOMEIP

前言 首先&#xff0c;请问大家几个小小问题&#xff0c;你清楚&#xff1a; 你知道什么是SOME/IP吗&#xff1f;你知道为什么会产生SOME/IP即相关背景吗&#xff1f;你知道SOME/IP与SOA又有着哪些千丝万缕的联系呢&#xff1f;SOME/IP在实践中到底应该如何使用呢&#xff1f…

QuickList

基本概述 ZipList虽节省内存但是申请内存必须是连续的&#xff0c;如果内存占用很大&#xff0c;申请内存效率就会很低&#xff0c;可以限制ZipList长度和entry大小&#xff1b; 实在要存储大量数据&#xff0c;超出ZipList最佳上限了&#xff0c;此时可以创建多个ZipList来分片…

Autosar诊断实战系列04-基于CAPL语言的通信类诊断测试脚本开发

本文框架 前言1.CAPL编程简单介绍2. CAPL脚本开发实战2.1 添加CAPL Test Module2.2 CAPL脚本实战编写前言 在本系列笔者将结合工作中对诊断实战部分的应用经验进一步介绍常用UDS服务的进一步探讨及开发中注意事项, Dem/Dcm/CanTp/Fim模块配置开发及注意事项,诊断与BswM/NvM关…

OpenAI官方提示词课(五)如何进行文本翻译校正修改

在本篇文章中&#xff0c;我们将探讨如何使用大语言模型进行文本转换任务&#xff0c;例如语言翻译、拼写和语法检查、语气调整和格式转换。 翻译 ChatGPT接受多种语言的训练&#xff0c;使得模型具备翻译能力。以下是如何使用这种能力的一些示例。 prompt f""&q…

利用lambda优化反射功能实现方法调用

最近在思考lambda相关的问题&#xff0c;简单记录下做的相关反射替代和函数映射的尝试。 原理分析 lambda是jdk8才提供的&#xff0c;原理其实就是动态生成内部类来执行函数映射的方法。也就是说一段lambda表达式会对应特定的类方法&#xff0c;之后调用。底层是通过LambdaMe…

《离散数学》:逻辑

〇、前言 离散数学是数学的一个分支&#xff0c;研究离散对象和离散结构的数学理论和方法。这学期学校开了离散数学的课程&#xff0c;我受益颇丰&#xff0c;感觉到了离散数学真正的魅力&#xff0c;也被开创离散数学各个分支的人的聪明与才智深深折服。与连续数学不同&#…

Stopwatch工具类计时器探究

搬砖的我们 特别是Java开发的童鞋们, 经常需要通过记录开始时间和结束时间&#xff0c;然后通过计算差值&#xff0c;得到时间差&#xff0c;如下面的代码&#xff1a; long start System.currentTimeMillis(); long end System.currentTimeMillis(); System.out.println(…

【数字调制】数字调制技术FSK与PSK分析与研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

栈的数据结构完成表达式(5*10+2-7+5)/10+5的计算

栈&#xff08;Stack&#xff09;是一种线性数据结构&#xff0c;具有后进先出&#xff08;LIFO&#xff09;的特性。它可以理解为一种类似于抽屉的容器&#xff0c;只能在顶部进行插入和删除操作&#xff0c;其他位置不可访问。栈的基本操作包括入栈&#xff08;push&#xff…

[数字图像处理]第五章 图像复原与重建

文章目录 第五章 图像复原与重建5.1图像退化复原过程的模型图像退化图像复原图像复原与图像增强图像退化的数学模型为什么采用线性位移不变系统模型来描述图像退化过程 5.2 噪声模型x5.2.1 噪声的空间和频率特性5.2.2 一些重要的噪声概率密度函数高斯噪声实验&#xff1a;采用高…

【微服务架构设计和实现】4.1 微服务架构概述和设计原则

往期回顾&#xff1a; 第一章&#xff1a;【云原生概念和技术】 第二章&#xff1a;【容器化应用程序设计和开发】 第三章&#xff1a;【基于容器的部署、管理和扩展】 4.1 微服务架构概述和设计原则 4.1 微服务架构概述和设计原则4.1.1 微服务架构的优点4.1.2 微服务架构遵…