30. 利用linprog 解决 生产决策问题(matlab程序)

news2024/9/20 7:55:21

1.简述

      

     线线规划的几个基本性质:【文献[1]第46页】

       (1)线性规划问题的可行域如果非空,则是一个凸集-凸多面体;

       (2)如果线性规划问题有最优解,那么最优解可在可行域的顶点中确定;

       (3)如果可行域有界,且可行域只有有限个顶点,则问题的最优解必存在,并在这有限个顶点中确定;

       (4)最优解可由最优顶点处的有效约束形成的方程组的解确定。

       常用的线性规划求解方法有单纯形法和内点法。

1、单纯形法(simplex method)

       单纯形法是由G.B. Dantzig在1947年提出来的,这是20世纪数学界最重大的成果之一。单纯形法是一种迭代法,它根据线性规划问题的特点在问题可行域的顶点中逐步确定问题的最优解。在每一个是基本可行解的迭代点(即顶点),如果它不是最优的,单纯形法从与该顶点相连结的边中确定一个使目标函数值下降的边,沿该边移动可以确定一个与该顶点相邻且目标函数又优于该顶点的新顶点(新的基本可行解)。由于可行域的顶点数是有限的,如果每一次的移动都能使目标函数值下降,则经过有限次的移动方法必终止于问题的一个最优顶点。【文献[1]第57页】

       单纯形法要求线性规划具有标准形式,即


即约束函数都是等式约束,且决策变量均是非负的。

       任何线性规划问题使用单纯形法时都需要通过变换转换为线性规划的标准形。转换方法参见文献[1]第51页例2.1.6。

2、从单纯形法到内点法

       由于单纯形法的有效性,几十年来得到了广泛的应用。近年来,对于大规模的线性规划问题,尽管单纯形法受到了内点法的挑战,但单纯形法还是受到广大用户的青睐。

       一个算法如果其求得问题的解所用的运算工作量是问题的参数m和n的多项式,则称这一算法的复杂多项式时间算法;如果所需运算工作量的阶数是以m或n为幂的指数2m或2n,则称复杂性是指数时间的算法。

       单纯形算法的平均运算工作量是多项式时间的,但对于一个具体的问题其算法的复杂性并不一定是多项式的。1972年,Klee和Minty给出了一个复杂性为指数时间的例子。那么对线性规划问题是否存在时间复杂性是多项式的算法呢?如果存在多项式时间算法,如何设计这样的算法?

       1979年,前苏联数学家Khachiyan回答了第1个问题,他提出了一个椭球算法求不等式问题的解,并证明了算法的时间复杂性是多项式的。利用对偶理论,线性规划问题可以转换成不等式问题,这就明确回答了对线性规划存在多项式时间算法。但是计算的实际表明,椭球算法的效果要比单纯形方法差得多,并不是一个有实际应用价值的算法。

       1984年,在美国贝尔实验室工作的印度数学家Karmarkar回答了第2个问题,它对线性规划的求解提出了一个具有多项式时间复杂性的内点算法。

3、内点法(interior point method)

       求线性规划问题的单纯形方法在问题的基本可行解中确定最优解,在几何上,每次迭代它是沿着可行域的边界从一个顶点向另一个更好的顶点移动来实现的。内点算法则完全不同,它是从可行域的一个严格内点开始,产生一个使目标函数值逐步改善的严格内点序列,并最终收敛于问题的最优解。通过下图可以清晰的看出单纯形法与内点法的区别。


单纯形法与内战法轨迹(文献[1]图2.4.4)

       经过近20年的研究与发展,如今已有大量求解线性规划问题的内点算法,它们可以分成三类:路径跟踪算法,仿射调比算法,和原始对偶内点算法(primal-dual interior point method)。

4、线性规划问题的MATLAB求解

       在MATLAB中求解线性规划问题的函数是linprog,该函数集中了几种求线性规划的算法,如内点法和单纯形法,根据问题的规模或用户指定的算法进行求解。具体使用方法可查询帮助文件。


 

 

2.代码

 

主程序:

%%  生产决策问题
f=[-5;-7]; %线性方程系数
A=[4,2;5,4;2,7;-6,-5;]; %线性不等式约束系数矩阵
b=[90;200;210;0];  
l=[0 0];   %变量上限
[xo,fo,exitflag]=linprog(f,A,b,[],[],l)

 

 

子程序:

function [x,fval,exitflag,output,lambda]=linprog(f,A,B,Aeq,Beq,lb,ub,x0,options)
%LINPROG Linear programming.
%   X = LINPROG(f,A,b) attempts to solve the linear programming problem:
%
%            min f'*x    subject to:   A*x <= b
%             x
%
%   X = LINPROG(f,A,b,Aeq,beq) solves the problem above while additionally
%   satisfying the equality constraints Aeq*x = beq. (Set A=[] and B=[] if
%   no inequalities exist.)
%
%   X = LINPROG(f,A,b,Aeq,beq,LB,UB) defines a set of lower and upper
%   bounds on the design variables, X, so that the solution is in
%   the range LB <= X <= UB. Use empty matrices for LB and UB
%   if no bounds exist. Set LB(i) = -Inf if X(i) is unbounded below;
%   set UB(i) = Inf if X(i) is unbounded above.
%
%   X = LINPROG(f,A,b,Aeq,beq,LB,UB,X0) sets the starting point to X0. This
%   option is only available with the active-set algorithm. The default
%   interior point algorithm will ignore any non-empty starting point.
%
%   X = LINPROG(PROBLEM) finds the minimum for PROBLEM. PROBLEM is a
%   structure with the vector 'f' in PROBLEM.f, the linear inequality
%   constraints in PROBLEM.Aineq and PROBLEM.bineq, the linear equality
%   constraints in PROBLEM.Aeq and PROBLEM.beq, the lower bounds in
%   PROBLEM.lb, the upper bounds in  PROBLEM.ub, the start point
%   in PROBLEM.x0, the options structure in PROBLEM.options, and solver
%   name 'linprog' in PROBLEM.solver. Use this syntax to solve at the
%   command line a problem exported from OPTIMTOOL.
%
%   [X,FVAL] = LINPROG(f,A,b) returns the value of the objective function
%   at X: FVAL = f'*X.
%
%   [X,FVAL,EXITFLAG] = LINPROG(f,A,b) returns an EXITFLAG that describes
%   the exit condition. Possible values of EXITFLAG and the corresponding
%   exit conditions are
%
%     3  LINPROG converged to a solution X with poor constraint feasibility.
%     1  LINPROG converged to a solution X.
%     0  Maximum number of iterations reached.
%    -2  No feasible point found.
%    -3  Problem is unbounded.
%    -4  NaN value encountered during execution of algorithm.
%    -5  Both primal and dual problems are infeasible.
%    -7  Magnitude of search direction became too small; no further
%         progress can be made. The problem is ill-posed or badly
%         conditioned.
%    -9  LINPROG lost feasibility probably due to ill-conditioned matrix.
%
%   [X,FVAL,EXITFLAG,OUTPUT] = LINPROG(f,A,b) returns a structure OUTPUT
%   with the number of iterations taken in OUTPUT.iterations, maximum of
%   constraint violations in OUTPUT.constrviolation, the type of
%   algorithm used in OUTPUT.algorithm, the number of conjugate gradient
%   iterations in OUTPUT.cgiterations (= 0, included for backward
%   compatibility), and the exit message in OUTPUT.message.
%
%   [X,FVAL,EXITFLAG,OUTPUT,LAMBDA] = LINPROG(f,A,b) returns the set of
%   Lagrangian multipliers LAMBDA, at the solution: LAMBDA.ineqlin for the
%   linear inequalities A, LAMBDA.eqlin for the linear equalities Aeq,
%   LAMBDA.lower for LB, and LAMBDA.upper for UB.
%
%   NOTE: the interior-point (the default) algorithm of LINPROG uses a
%         primal-dual method. Both the primal problem and the dual problem
%         must be feasible for convergence. Infeasibility messages of
%         either the primal or dual, or both, are given as appropriate. The
%         primal problem in standard form is
%              min f'*x such that A*x = b, x >= 0.
%         The dual problem is
%              max b'*y such that A'*y + s = f, s >= 0.
%
%   See also QUADPROG.

%   Copyright 1990-2018 The MathWorks, Inc.

% If just 'defaults' passed in, return the default options in X

% Default MaxIter, TolCon and TolFun is set to [] because its value depends
% on the algorithm.
defaultopt = struct( ...
    'Algorithm','dual-simplex', ...
    'Diagnostics','off', ...
    'Display','final', ...
    'LargeScale','on', ...
    'MaxIter',[], ...
    'MaxTime', Inf, ...
    'Preprocess','basic', ...
    'TolCon',[],...
    'TolFun',[]);

if nargin==1 && nargout <= 1 && strcmpi(f,'defaults')
   x = defaultopt;
   return
end

% Handle missing arguments
if nargin < 9
    options = [];
    % Check if x0 was omitted and options were passed instead
    if nargin == 8
        if isa(x0, 'struct') || isa(x0, 'optim.options.SolverOptions')
            options = x0;
            x0 = [];
        end
    else
        x0 = [];
        if nargin < 7
            ub = [];
            if nargin < 6
                lb = [];
                if nargin < 5
                    Beq = [];
                    if nargin < 4
                        Aeq = [];
                    end
                end
            end
        end
    end
end

% Detect problem structure input
problemInput = false;
if nargin == 1
    if isa(f,'struct')
        problemInput = true;
        [f,A,B,Aeq,Beq,lb,ub,x0,options] = separateOptimStruct(f);
    else % Single input and non-structure.
        error(message('optim:linprog:InputArg'));
    end
end

% No options passed. Set options directly to defaultopt after
allDefaultOpts = isempty(options);

% Prepare the options for the solver
options = prepareOptionsForSolver(options, 'linprog');

if nargin < 3 && ~problemInput
  error(message('optim:linprog:NotEnoughInputs'))
end

% Define algorithm strings
thisFcn  = 'linprog';
algIP    = 'interior-point-legacy';
algDSX   = 'dual-simplex';
algIP15b = 'interior-point';

% Check for non-double inputs
msg = isoptimargdbl(upper(thisFcn), {'f','A','b','Aeq','beq','LB','UB', 'X0'}, ...
                                      f,  A,  B,  Aeq,  Beq,  lb,  ub,   x0);
if ~isempty(msg)
    error('optim:linprog:NonDoubleInput',msg);
end

% After processing options for optionFeedback, etc., set options to default
% if no options were passed.
if allDefaultOpts
    % Options are all default
    options = defaultopt;
end

if nargout > 3
   computeConstrViolation = true;
   computeFirstOrderOpt = true;
   % Lagrange multipliers are needed to compute first-order optimality
   computeLambda = true;
else
   computeConstrViolation = false;
   computeFirstOrderOpt = false;
   computeLambda = false;
end

% Algorithm check:
% If Algorithm is empty, it is set to its default value.
algIsEmpty = ~isfield(options,'Algorithm') || isempty(options.Algorithm);
if ~algIsEmpty
    Algorithm = optimget(options,'Algorithm',defaultopt,'fast',allDefaultOpts);
    OUTPUT.algorithm = Algorithm;
    % Make sure the algorithm choice is valid
    if ~any(strcmp({algIP; algDSX; algIP15b},Algorithm))
        error(message('optim:linprog:InvalidAlgorithm'));
    end
else
    Algorithm = algDSX;
    OUTPUT.algorithm = Algorithm;
end

% Option LargeScale = 'off' is ignored
largescaleOn = strcmpi(optimget(options,'LargeScale',defaultopt,'fast',allDefaultOpts),'on');
if ~largescaleOn
    [linkTag, endLinkTag] = linkToAlgDefaultChangeCsh('linprog_warn_largescale');
    warning(message('optim:linprog:AlgOptsConflict', Algorithm, linkTag, endLinkTag));
end

% Options setup
diagnostics = strcmpi(optimget(options,'Diagnostics',defaultopt,'fast',allDefaultOpts),'on');
switch optimget(options,'Display',defaultopt,'fast',allDefaultOpts)
    case {'final','final-detailed'}
        verbosity = 1;
    case {'off','none'}
        verbosity = 0;
    case {'iter','iter-detailed'}
        verbosity = 2;
    case {'testing'}
        verbosity = 3;
    otherwise
        verbosity = 1;
end

% Set the constraints up: defaults and check size
[nineqcstr,nvarsineq] = size(A);
[neqcstr,nvarseq] = size(Aeq);
nvars = max([length(f),nvarsineq,nvarseq]); % In case A is empty

if nvars == 0
    % The problem is empty possibly due to some error in input.
    error(message('optim:linprog:EmptyProblem'));
end

if isempty(f), f=zeros(nvars,1); end
if isempty(A), A=zeros(0,nvars); end
if isempty(B), B=zeros(0,1); end
if isempty(Aeq), Aeq=zeros(0,nvars); end
if isempty(Beq), Beq=zeros(0,1); end

% Set to column vectors
f = f(:);
B = B(:);
Beq = Beq(:);

if ~isequal(length(B),nineqcstr)
    error(message('optim:linprog:SizeMismatchRowsOfA'));
elseif ~isequal(length(Beq),neqcstr)
    error(message('optim:linprog:SizeMismatchRowsOfAeq'));
elseif ~isequal(length(f),nvarsineq) && ~isempty(A)
    error(message('optim:linprog:SizeMismatchColsOfA'));
elseif ~isequal(length(f),nvarseq) && ~isempty(Aeq)
    error(message('optim:linprog:SizeMismatchColsOfAeq'));
end

[x0,lb,ub,msg] = checkbounds(x0,lb,ub,nvars);
if ~isempty(msg)
   exitflag = -2;
   x = x0; fval = []; lambda = [];
   output.iterations = 0;
   output.constrviolation = [];
   output.firstorderopt = [];
   output.algorithm = ''; % not known at this stage
   output.cgiterations = [];
   output.message = msg;
   if verbosity > 0
      disp(msg)
   end
   return
end

if diagnostics
   % Do diagnostics on information so far
   gradflag = []; hessflag = []; constflag = false; gradconstflag = false;
   non_eq=0;non_ineq=0; lin_eq=size(Aeq,1); lin_ineq=size(A,1); XOUT=ones(nvars,1);
   funfcn{1} = []; confcn{1}=[];
   diagnose('linprog',OUTPUT,gradflag,hessflag,constflag,gradconstflag,...
      XOUT,non_eq,non_ineq,lin_eq,lin_ineq,lb,ub,funfcn,confcn);
end

% Throw warning that x0 is ignored (true for all algorithms)
if ~isempty(x0) && verbosity > 0
    fprintf(getString(message('optim:linprog:IgnoreX0',Algorithm)));
end

if strcmpi(Algorithm,algIP)
    % Set the default values of TolFun and MaxIter for this algorithm
    defaultopt.TolFun = 1e-8;
    defaultopt.MaxIter = 85;
    [x,fval,lambda,exitflag,output] = lipsol(f,A,B,Aeq,Beq,lb,ub,options,defaultopt,computeLambda);
elseif strcmpi(Algorithm,algDSX) || strcmpi(Algorithm,algIP15b)

    % Create linprog options object
    algoptions = optimoptions('linprog', 'Algorithm', Algorithm);

    % Set some algorithm specific options
    if isfield(options, 'InternalOptions')
        algoptions = setInternalOptions(algoptions, options.InternalOptions);
    end

    thisMaxIter = optimget(options,'MaxIter',defaultopt,'fast',allDefaultOpts);
    if strcmpi(Algorithm,algIP15b)
        if ischar(thisMaxIter)
            error(message('optim:linprog:InvalidMaxIter'));
        end
    end
    if strcmpi(Algorithm,algDSX)
        algoptions.Preprocess = optimget(options,'Preprocess',defaultopt,'fast',allDefaultOpts);
        algoptions.MaxTime = optimget(options,'MaxTime',defaultopt,'fast',allDefaultOpts);
        if ischar(thisMaxIter) && ...
                ~strcmpi(thisMaxIter,'10*(numberofequalities+numberofinequalities+numberofvariables)')
            error(message('optim:linprog:InvalidMaxIter'));
        end
    end

    % Set options common to dual-simplex and interior-point-r2015b
    algoptions.Diagnostics = optimget(options,'Diagnostics',defaultopt,'fast',allDefaultOpts);
    algoptions.Display = optimget(options,'Display',defaultopt,'fast',allDefaultOpts);
    thisTolCon = optimget(options,'TolCon',defaultopt,'fast',allDefaultOpts);
    if ~isempty(thisTolCon)
        algoptions.TolCon = thisTolCon;
    end
    thisTolFun = optimget(options,'TolFun',defaultopt,'fast',allDefaultOpts);
    if ~isempty(thisTolFun)
        algoptions.TolFun = thisTolFun;
    end
    if ~isempty(thisMaxIter) && ~ischar(thisMaxIter)
        % At this point, thisMaxIter is either
        % * a double that we can set in the options object or
        % * the default string, which we do not have to set as algoptions
        % is constructed with MaxIter at its default value
        algoptions.MaxIter = thisMaxIter;
    end

    % Create a problem structure. Individually creating each field is quicker
    % than one call to struct
    problem.f = f;
    problem.Aineq = A;
    problem.bineq = B;
    problem.Aeq = Aeq;
    problem.beq = Beq;
    problem.lb = lb;
    problem.ub = ub;
    problem.options = algoptions;
    problem.solver = 'linprog';

    % Create the algorithm from the options.
    algorithm = createAlgorithm(problem.options);

    % Check that we can run the problem.
    try
        problem = checkRun(algorithm, problem, 'linprog');
    catch ME
        throw(ME);
    end

    % Run the algorithm
    [x, fval, exitflag, output, lambda] = run(algorithm, problem);

    % If exitflag is {NaN, <aString>}, this means an internal error has been
    % thrown. The internal exit code is held in exitflag{2}.
    if iscell(exitflag) && isnan(exitflag{1})
        handleInternalError(exitflag{2}, 'linprog');
    end

end

output.algorithm = Algorithm;

% Compute constraint violation when x is not empty (interior-point/simplex presolve
% can return empty x).
if computeConstrViolation && ~isempty(x)
    output.constrviolation = max([0; norm(Aeq*x-Beq, inf); (lb-x); (x-ub); (A*x-B)]);
else
    output.constrviolation = [];
end

% Compute first order optimality if needed. This information does not come
% from either qpsub, lipsol, or simplex.
if exitflag ~= -9 && computeFirstOrderOpt && ~isempty(lambda)
    output.firstorderopt = computeKKTErrorForQPLP([],f,A,B,Aeq,Beq,lb,ub,lambda,x);
else
    output.firstorderopt = [];
end

 

 

3.运行结果

 

b2f4f6a2504743a592d694bb308fdb13.png

 

 

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

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

相关文章

【数据中台】DataX源码进行二开插件

参考官方 使用的离线数据同步工具/平台&#xff0c;实现不同数据库等各种异构数据源之间高效的数据同步功能 工具部署 https://github.com/alibaba/DataX/blob/master/userGuid.md 拉取下来的代码&#xff0c;pom.xml里面注释 <!--<module>tsdbreader</module&g…

大整数截取解决方法(java代码)

大整数截取解决方法&#xff08;java代码&#xff09; 描述输入描述输出描述输入示例输出示例前置知识&#xff1a;代码 解题思路来自这个博客&#xff1a;简单^不简单 https://blog.csdn.net/younger_china/article/details/126376374 描述 花花有一个很珍贵的数字串&#xf…

P4053 [JSOI2007] 建筑抢修(贪心)(内附封面)

[JSOI2007] 建筑抢修 题目描述 小刚在玩 JSOI 提供的一个称之为“建筑抢修”的电脑游戏&#xff1a;经过了一场激烈的战斗&#xff0c;T 部落消灭了所有 Z 部落的入侵者。但是 T 部落的基地里已经有 N N N 个建筑设施受到了严重的损伤&#xff0c;如果不尽快修复的话&#x…

python项目开发案例集锦,python开发程序流程

大家好&#xff0c;给大家分享一下python项目开发案例集锦 源码&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 今天任务 1.创建Python项目为pythontest1以及test1.py文件 2.修改字号 3.输入九九乘法表程序&#xff0c;编译调试执行 4.配置…

Python selenium对应的浏览器chromedriver版本不一致

1、chrome和chromedriver版本不一致导致的&#xff0c;我们只需要升级下chromedriver的版本即可 浏览器版本查看 //打开google浏览器直接访问&#xff0c;查看浏览器版本 chrome://version/ 查看chromedriver的版本 //查看驱动版本 chromedriver chromedriver下载 可看到浏…

基于 Debian GNU/Linux 12 “书虫 “的Neptune 8.0 “Juna “来了

导读Neptune Linux 发行版背后的团队发布了 Neptune 8.0&#xff0c;作为这个基于 Debian 的 GNU/Linux 发行版的重大更新&#xff0c;它围绕最新的 KDE Plasma 桌面环境构建。 Neptune 8.0 被命名为 “Juna”&#xff0c;是在Neptune 7.5 发布 11 个月后发布的&#xff0c;也是…

2.1 密码学基础

数据参考&#xff1a;CISP官方 目录 密码学基本概念对称密码算法非对称密码算法哈希函数与数字签名公钥基础设施 一、密码学基本概念 1、密码学形成与发展 发展历程 古典密码学 (1949年之前) 主要特点&#xff1a;数据的安全基于算法的保密 近代密码学 (1949~1975年…

第4章 案例研究:JavaScript图片库

案例 html部分 <h1 id"title">图片1</h1> <ul><li><!-- onclick绑定点击事件&#xff0c;this为触发dom&#xff0c;return false阻止默认行为 --><a onclick"show_img(this); return false" title"图片1" h…

数字信号处理中的基本运算——乘法运算

一、二进制乘法原理 二进制乘法可分为&#xff1a;无符号乘法和有符号乘法 整个相乘过程可分解为一系列的移位、相加操作。 有符号数乘法可分为&#xff1a;&#xff08;1&#xff09;正数*正数&#xff1b;&#xff08;2&#xff09;正数*负数&#xff1b;&#xff08;3&…

申请软件著作权都有什么好处?

随着社会的发展&#xff0c;知识产权保护意识对于公司而言尤为重要&#xff0c;对自己的权利进行最大限度的保护&#xff0c;以防止被别有用心的人侵权。那么&#xff0c;申请软著的好处到底是什么?软著有什么用呢? 无形资产软著是一种无形的知识产权&#xff0c;是开发者智慧…

(常压)室温超导体:The First Room-Temperature Ambient-Pressure Superconductor

2023年7月23日&#xff0c;一支韩国的研究团队声称他们已经成功研制出了一种在室温和常压下的超导体&#xff0c;名为LK-99。这一发现在科学界引起了广泛的关注和讨论。 然而&#xff0c;这项研究的结果也引起了一些科学家的怀疑。有些人对数据的真实性表示了疑虑&#xff0c;认…

【UEC++学习】UE网络 - Replication、RPC

1. UE网络架构 &#xff08;1&#xff09;UE的网络架构是SC&#xff08;Server - Client&#xff09;的模式&#xff0c;这种模式的优势&#xff1a;这种模式让所有客户端都在服务器端进行安全验证&#xff0c;这样可以有效的防止客户端上的作弊问题。 &#xff08;2&#xff…

【编程范式】聊聊什么是数据类型和范式的本质

什么是编程范式 范式其实就是做事的方式&#xff0c;编程范式可以理解为如何编程&#xff0c;按照什么样的模式或者风格进行编程。 编程范式包含哪些 泛型编程函数式编程面向对象编程编程本质和逻辑编程 虽然有不同的编程范式&#xff0c;但是对于目的来说都是为了解决同一…

关于vs下多态虚表中存储的地址和实际成员函数地址不一样的原因

以如下代码为例&#xff1a; class Base1 { public: virtual void func1() { cout << "Base1::func1" << endl; } virtual void func2() { cout << "Base1::func2" << endl; } private: int b1; }; class Base2 { public: virtual…

BES 平台 SDK之LED的配置

本文章是基于BES2700 芯片&#xff0c;其他BESxxx 芯片可做参考&#xff0c;如有不当之处&#xff0c;欢迎评论区留言指出。仅供参考学习用&#xff01; BES 平台 SDK之代码架构讲解二_谢文浩的博客-CSDN博客 关于SDK 系统框架简介可参考上一篇文章。链接如上所示&#xff01…

学python需要下载什么软件,自学python需要安装什么

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;学python需要安装一些什么软件好&#xff0c;学python需要安装一些什么软件&#xff0c;今天让我们一起来看看吧&#xff01; 工欲善其事必先利其器。初学者在学Python的时候&#xff0c;往往会因为没有好用的软件工具&…

2.5 BUMP图改进

一、Bump Mapping介绍 凹凸贴图映射技术是对物体表面贴图进行变化然后进行光计算的一种技术。例如给法线分量添加噪音&#xff0c;或者在一个保护扰动值的纹理图中进行查找。这是一个提升物理真实感的有效方法&#xff0c;但却不需要额外的提升物体的几何复杂度。这种法式在提…

华为OD机试真题 Java 实现【简单的自动曝光】【2023Q1 100分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、备注五、解题思路六、Java算法源码七、效果展示1、输入2、输出3、说明4、再输入5、输出6、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff…

【雕爷学编程】Arduino动手做(173)---SG90舵机双轴云台模块2

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

数据库事务--springboot事务处理

二、简单事务使用 模拟一 1、数据库 db.sql drop database if exists supermarket; create database supermarket; use supermarket; drop table if exists order_item; CREATE TABLE order_item (item_id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 订单ID,order_no …