1、Pyomo 简介

pyomo文档【数学建模】优化模型建模语言 Pyomo 入门教程 - 知乎 (zhihu.com)

Pyomo 是基于 Python 的开源软件包,主要功能是建立数学规划模型,包括线性规划,二次规划,整数规划,随机规划,含有微分代数方程的优化问题。

这里需要注意两个问题:

  1. Pyomo 只负责建模,求解还需要调用求解器来求解
  2. Pyomo 是开源免费的,但是只能适用于Python环境

你可能会产生一个疑问,在Gurobi/Cplex之类的求解器中也可以直接写模型啊,为何还需要专门单独搞一个Pyomo来写模型呢?主要是因为如下原因:

  1. Pyomo 的建模功能比一般求解器中自带的建模功能强大,Pyomo 支持多种问题类型,包括:
  • 线性规划
  • 二次规划
  • 非线性规划
  • 整数线性规划
  • 混合整数非线性规划
  • 混合整数二次规划
  • 微分代数方程
  • 整数随机规划
  • 广义析取规划
  • 带平衡约束的数学规划

这些都是 Gurobi/Cplex 所不具备的。

  1. 采用 Pyomo 建模可以实现一次建模,通用求解。在 Pyomo 中建模后 可以非常方便地调用其它多种求解器来求解,例如 Gurobi,Cplex,SCIP,CBC等。

所以是否选用 Pyomo 大家可以根据以上两条对照自己的需求来决定。最后 Pyomo 的安装也非常方便,在Anaconda环境中直接采用pip即可安装

pip install pyomo

2、Pyomo 建模方法

可通过两种方式使用 Pyomo 创建优化模型:抽象(Abstract)和具体(Concrete)。这两种方式的关键区别在于是否将模型与数据分开引入:

  • 在抽象模型中,模型与数据是分开的,支持在模型建立后再引入数据赋值。
  • 在具体模型中,数据在模型本身中被定义。例如,在使用具体模型的 Pyomo 脚本中,所有内容都是在单个脚本文件中定义的。对于简单的问题,这可能是一种很高效的方法。但另一方面,对于规模比较大的问题(更大的数据集),这使得将数据和处理该数据所需的代码嵌入同一个Python脚本中变得不易实现且难以维护。

总体上讲,Pyomo 模型由变量(Variables)、参数(Parameters)、约束(Constraints)和目标(Objectives)组成。

(1)变量(Variables):

变量代表模型中待优化的决策变量,它是在优化求解中待计算的对象。求解优化模型后得到的变量的值通常称为解,它是优化求解过程的输出。

(2)参数(Parameters):

参数通常指优化问题中提供的数据(系数),以便为决策变量找到最佳(或良好)的值分配。参数值也可以通过定义验证函数进行检查。

(3)约束(Constraints):

约束是定义等式、不等式或其他数学表达式来指定变量的限制的一种方式。大多数约束是使用表达式规则创建的,这些规则往往是一个 Python 函数。

(4)优化目标(Objective):

优化目标是指被建模系统的目标的函数,一般有最大化或最小化两种定义。

注意:建模过程中表达式不能用怒 numpy 等科学计算包

3、基本案例

from pyomo.environ import *
model = ConcreteModel()
model.x = Var(RangeSet(1, 4), bounds=(1, 5))
model.cons1 = Constraint(rule=lambda model: 40==model.x[1]**2+model.x[2]**2+model.x[3]**2+model.x[4]**2)
model.cons2 = Constraint(rule=lambda model: 25<=model.x[1]*model.x[2]*model.x[3]*model.x[4])
model.obj = Objective(expr = model.x[1]*model.x[4]*(model.x[1] + model.x[2] + model.x[3]) + model.x[3], sense=minimize)
SolverFactory('ipopt').solve(model)
solutions = [model.x[i]() for i in range(1, 5)]
print("solutins is :"+str(solutions))

在这里我们只使用 model = ConcreteModel() 来定义模型,在 Pyomo 中还有另外一类抽象的 AbstractModel() 模型,相对来说该模型的使用更加高级。

4、建模六大要素

从运筹优化的理论来讲,一般优化模型的构成是三大要素 决策变量,约束,目标函数。但是在用代码实现优化模型的时候就不得不考虑另外三个不可或缺的要素:索引集合、参数和表达式。因此一共合成六大要素,

  • 索引集合
  • 参数
  • 决策变量
  • 目标函数
  • 约束条件
  • 表达式

在 Pyomo 中我们只要定义好了以上六大要素,也就基本完成了对优化问题的建模。下面以优化问题中常见的指派问题为例来说明这六大要素:

4.1 索引集合

Pyomo 中常用的两类集合

4.1.1 Set(initialize, filter, validate)

  • initialize:表示初始化参数,可以采用列表,元组和集合来给一个Set初始化;
  • filter:表示一个过滤掉集合的条件,一般是一个函数表达式;
  • validate:表示对集合进行验证条件,一般是一个函数表达式;

如下所示是采用多种方式来初始化集合的方法:

from pyomo.environ import *
model = ConcreteModel()
model.I = Set(initialize = [i for i in range(6)]) # 采用列表初始化集合
model.J = Set(initialize=('red', 'green', 'blue')) # 采用元组初始化集合 并且用字符串作为元素引。
model.N = Set([i for i in range(3)]) # 等价于用 initialize
model.M = Set([(i,j) for i in range(2) for j in range(2)])
def even_init(model):
return (i for i in model.I if i % 2 == 0)
model.K = Set(initialize=even_init) # 可以通过一个函数even_init 来定义initialize,本例中就是选取偶数的索引。

采用filter参数可以对集合的元素进行筛选,如下例子中就是通过定义 filter_rule 来实现让model.P集合中只含有集合model.I 没有的元素

def filter_rule(model, x):
return x not in model.I model.P = Set(initialize = [i for i in range(6)], filter = filter_rule)

4.1.2 RangeSet(start, end, slice)

如果只需要纯数字作为索引的元素采用RangeSet会更加直接和方便一些,当然前面介绍的 Set 的功能可以覆盖掉 RangeSet。RangeSet 的用法如下所示:

model.D = RangeSet(1,10,2) # 表示 [1,3,5,7,9]
# model.D = RangeSet(10) # 表示
# model.D = RangeSet(1,10,4) 表示 [1,5,9]
# model.D = RangeSet(1,10) 表示 [1,2,3,4,5,6,7,8,9,10]

4.1.3 集合的运算

model.I = [i for i in range(5)] # 给集合赋值
print([v for v in model.I]) # 遍历集合中所有元素
print(len(model.J)) # 3 表示集合元素个数
print(model.I.data()) # (0, 1, 2, 3, 4) 表示 集合元素
print(model.J.data()) # ('red', 'green', 'blue') 表示 集合元素
print(1 in model.I) # True 判断元素是否在集合内
print(12 in model.I) # False 判断元素是否在集合内
print([1,2] == model.I) # False 判断集合是否相等
print([i for i in range(5)] == model.I) # True 判断集合是否相等

Pyomo 提供了几种集合之间的运算,这些运算与Python自带的集合类型十分相似。我这里列举在运筹优化中最常见的四种运算:并交差,笛卡尔积。

model.I = [i for i in range(6)]
model.J = [i for i in range(6) if i % 2 == 0]
model.K = [1,2]
model.E = model.I & model.J # 交集 (0, 2, 4)
model.F = model.I - model.J # 差集 (1, 3, 5)
model.G = model.I | model.J # 并集 (0, 1, 2, 3, 4, 5)
model.H = model.J * model.K # 笛卡尔积 ((0, 1), (0, 2), (2, 1), (2, 2), (4, 1), (4, 2))

4.2 参数

Param(initialize, default, validate)

  • initialize:表示初始化参数,可以采用列表,元组和字典来做参数初始化;
  • default:表示初始化参数的默认值,initialize没有覆盖的索引default才会起作用;
  • validate: 表示对集合进行验证条件,一般是一个函数表达式

4.2.1 简单赋值法初始化参数

from pyomo.environ import *
model = ConcreteModel()
model.I = Set(initialize = [i for i in range(4)])
model.J = Set(initialize = [i for i in range(4)])
model.c = Param(model.I, model.J, default = 1) # 参数c是一个4*4的矩阵 并且初始值全部为1

4.2.2 字典初始化参数

c_data = {(0,0): 1, (1,2): 33, (3,3): 20} # 采用字典初始化 表示 c[0,0]=1,c[1,2]=33,c[3,3]=20
model.c1 = Param(model.I, model.J, initialize=c_data, default = 0) # default = 0 表示其余元素都为 0

4.2.3 函数初始化参数

采用函数初始化参数相比前两种方法可以非常的灵活。

def c_init(model, i, j):
if i == j:
return i*i
else:
return 0.0 model.c2 = Param(model.I, model.J, initialize=c_init)

4.2.4 validate 验证参数取值正确性

借用 c_validate 函数可以方便验证参数选取是否满足一些硬性条件,如果不满足条件则会直接报错提示。这是一个非常好的预防bug提升代码鲁棒性的功能,同时validate并不影响我们对数学模型的实现。

c_data = {(1,1): 4, (1,2): 33, (3,3): 20}
def c_validate(model, v, i, j): # 保证所有c_{ij}的值都要大于3
return v > 3. model.c3 = Param(model.I, model.J, initialize=c_data, validate=c_validate)

在上面的代码中,如果\(c_{ij}\)的值小于3,validate函数会报错提示我们。

4.2.5 参数常用操作

print(len(model.c)) # 9 参数元素个数
print(1 in model.c) # False
print((0,0) in model.c) # True
print([v for v in model.c]) # [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2

4.3 决策变量

Var(index_set, within, bounds, initialize)

  • index_set: 表示决策变量的索引;
  • bounds:表示决策变量上下界;
  • within :表示决策变量类型;
  • initialize :表示决策变量的初值;

4.3.1 一维决策变量定义

from pyomo.environ import *
model = ConcreteModel()
# Reals 表示实数变量,上下界为0-6,初始值设为1.5
model.x = Var(within=Reals, bounds=(0,6), initialize=1.5)

4.3.2 多维决策变量定义

def fb(model, i, j):
return (0, 1) # 下界为0,上界为1 model.I = Set(initialize = [i for i in range(4)])
model.J = Set(initialize = [i for i in range(4)])
model.y= Var(model.I, model.J, within=PositiveIntegers, bounds=fb)
# 表示决策变量 y 维数为4*4,正整数变量,上下通过函数fb()定义
def fb1(model, i, j):
return (10, None) # None表示没有上界 model.z= Var(model.I, model.J, within=PositiveIntegers, bounds=fb1)

within 可以选择的类型有:

Reals: 实数

PositiveReals:正实数

NonPositiveReals: 非正实数

NegativeReals:负实数

NonNegativeReals:非负实数

PercentFraction: 0到1之间实数

UnitInterval: 同PercentFraction

Integers:整数

PositiveIntegers:正整数

NonPositiveIntegers:非正整数

NegativeIntegers:负整数

NonNegativeIntegers:非负整数

Boolean: 布尔变量

Binary: 0,1变量

4.3.3 给决策变量赋初值

给决策变量赋初值是一个很重要的功能,因为很多算法都涉及到 warm start 的问题,给决策变量赋一个好的初值会加速整个求解过程。在 pyomo 中就是通过initialize参数来实现给决策变量赋初值的功能,相关代码如下所示:

model.x_init1 = Var(model.I, model.J, initialize = {(0,0):1.2, (1,2):30, (2,2): 21}) # 字典赋初值给决策变量
model.x_init2 = Var(model.I, model.J, initialize = 2.0) # 初值全为 2.0
def g_init(model, i, j):
return i+j model.x_init3 = Var(model.I, model.J, initialize = g_init) # 通过函数g_init 给定初值
print(value(model.x_init1[0,0])) # 1.2
print(value(model.x_init1[1,2])) # 30
print(value(model.x_init2[0,0])) # 2.0
print(value(model.x_init2[3,3])) # 2.0
print(value(model.x_init3[3,3])) # 6.0

4.3.4 决策变量的固定

在优化算法中我们为了降低问题的规模,经常会采用固定住一部分决策变量,只优化另外一部分决策变量的策略。这种直观的方法也被称为 fixed and relaxed 。在 Pyomo中也给我们提供了这样固定住决策变量的方法,一旦变量被固定住之后 在优化求解过程中该变量均被视为常数 不会被改变,代码如下所示:

model.x_init1.fix(1) # 表示把 x_init1 决策变量固定为1
print(model.x_init1[0,0].fixed) # True 表示该变量是固定变量
print(value(model.x_init1[0,0])) # 1

4.4 目标函数

Objective(index_set, obj_rule, sense)

  • index_set:表示目标函数索引集合;
  • obj_rule:表示目标函数定义规则;
  • sense:maximize代表是极大化问题,minimize代表极小化问题;

4.4.1 简单表达式定义目标函数

model = ConcreteModel()
model.I = Set(initialize = [i for i in range(2)])
model.J = Set(initialize = [i for i in range(3)])
model.x = Var(model.I, model.J, domain = Reals) def obj_rule(model):
return 2*model.x[1,1] + 3*model.x[1,2] model.obj1 = Objective(rule = obj_rule, sense=minimize)

4.4.2 借助summation函数定义目标函数

summation 函数是 pyomo 中可以实现两个向量快速求内积的操作,如下代码是实现目标函数

model.p = Param(model.I, model.J, default = 2)
def obj_rule(model):
return summation(model.p, model.x)
model.obj2 = Objective(rule = obj_rule, sense=maximize)

4.4.3 借助各种复杂表达式定义目标函数

Pyomo 中可以建模各种各样的目标函数,如下的目标函数中包括了三角函数,多项式函数,指数函数和对数函数。

def obj_rule(model):
expr = 0
for i in model.I:
for j in model.J:
expr += sin(model.x[i,j]) + model.x[i,j]**2 + 2**(model.x[i,j]) + log(model.x[i,j])
return expr model.obj3 = Objective(rule = obj_rule, sense=minimize)

4.4.4 带有索引的目标函数定义

如下所示是实现为目标函数。

def e_rule(model, i, j):
return model.x[i,j]**2
model.e1 = Objective(model.I, model.J, rule=e_rule)

4.4.5 借助 Skip 实现目标函数灵活定义

某些索引需要跳过的,可以采用 Objective.Skip,如下所示就是跳过 i 和 j相等的情况,就可以在对变矩阵选择性的执行函数。

def e_rule(model, i, j):
if i == j:
return Objective.Skip
return model.x[i,j]**2 model.e2 = Objective(model.I, model.J, rule=e_rule)

3.4.6 访问目标函数的性质

print(model.obj1.expr) # 2*x[1,1] + 3*x[2,2] 返回目标函数的表达式
print(model.obj1.sense) # -1 表示极大化 1 表示极小化
print(value(model.obj1)) # 返回目标函数值

4.5 约束

Objective(index_set, expr, rule)

  • index_set:表示约束索引集合;
  • rule:表示目约束定义规则;
  • expr:表示约束表达式;

4.5.1 借助表达式定义单条约束

借助表达式可以非常方便的定义简单的单条约束,如下所示:

model = ConcreteModel()
model.I = Set(initialize = [i for i in range(3)])
model.J = Set(initialize = [i for i in range(3)])
model.x = Var(model.I, model.J, initialize = 1.0, within = Reals)
model.c1 = Constraint(expr = 2.0 <= model.x[0,0] + 2*model.x[0,2]) # 不等式约束 2 <= x[0,0] + 2*x[0,2]
model.c2 = Constraint(expr = 3*model.x[0,0] + 5*model.x[1,1] == 10.0) # 等式约束 3*x[0,0] + 5*x[1,1] = 10.0 print(value(model.c1.body)) # 3 返回c1表达式的值
print(model.c1.lslack()) # 1.0 返回c1约束和下限的差(lower bound slack variable)
print(model.c1.uslack()) # +inf 返回c1约束和上限的差(upper bound slack variable)
print(model.c2.lslack()) # -2.0 返回c2约束和下限的差(lower bound slack variable)
print(model.c2.uslack()) # 2.0 返回c1约束和下限的差(upper bound slack variable)

注意:约束与下限差的计算是约束减下限,相反约束与上限的差是上限减约束。

4.5.2 借用函数定义单个约束

对于表达式比较复杂的约束,可以采用一个函数来定义这个约束,如下所示:

model.p = Param(model.I, model.J, default = 2)
def c3_rule(model):
return summation(model.p, model.x) + model.x[0,0]**2 <= 2 model.c3 = Constraint(rule = c3_rule)

4.5.3 借用函数定义多条约束

一次性定义多条约束,例如\sum_{j\in J}{p_{ij}x_{ij}}\le 2,\ \ \forall i\in I 。如果需要跳过某些不需要定义约束的索引下标,同理也可以采用 Constraint.Skip 就可以跳过相对应的下标。如下所示就是跳过了\(i=0\)的情况:

def c4_rule(model, i):
if i == 0:
return Constraint.Skip
return sum([model.p[i,j]*model.x[i,j] for j in model.J]) <= 2 model.c4= Constraint(model.I, rule = c4_rule)

c4_rule 函数会对 moel.I 的 i 循环执行,这样就构建了 I 个约束。

4.5.4 激活约束和停用约束

很多时候我们需要暂时让一些约束失效,那么 pyomo 也有这样的命令,如下所示:

model.c2.deactivate() # c2约束失效
model.c2.activate() # 重新激活c2约束

调用 deactivate() 后可以让约束c2不起作用了,如果想再添加回c2约束,再调用activate()即可。

4.6 表达式

Expression(expr, rule)

  • expr:表达式;
  • rule:定义表达式的函数;

4.6.1 定义单个表达式

定义单个表达式,如下所示是定义表达式x_0 + 3x_1,然后使用表达式的 set_value() 可以对表达式再赋值,同样借助 value() 函数可以得到表达式的值(在使用value函数返回表达式值之前确保所有表达式中的变量已经有值),代码如下所示。

from pyomo.environ import *
model = ConcreteModel()
model.I = Set(initialize = [i for i in range(3)])
model.x = Var(model.I, within = Reals, initialize = 1.0)
model.e = Expression(expr = model.x[0] + 3*model.x[1]) # 建立表达式e=x[0]+3x[1]
print(value(model.e)) # 4.0
model.e.set_value(model.x[1]) # 重新给表达式赋值 e = x[1]
print(value(model.e)) # 1.0

4.6.2 定义多个表达式

定义多个表达式,如下所示是定义表达式 i×x_i,i∈I

def expr_rule(model,i):
if i == 1:
return Expression.Skip
return model.x[i]*i model.e1 = Expression(model.I, rule=expr_rule)

定义多个表达式,如下所示是定义表达式x_i×x_i+e^x),i∈I

def gen_expr_rule(model,i):
return model.x[i]* model.x[i] + exp(model.x[i]) model.e2 = Expression(model.I, rule=gen_expr_rule)

4.6.3 采用单表达式辅助定义约束和目标函数

事实上定义表达式的一个很重要的目的是帮助我们定义约束和目标函数,例如下面的例子就是借助刚才定义的表达式来定义目标和约束。

model.obj = Objective(expr=0.1*model.e + model.x[0])
model.constr = Constraint(expr=model.e <= 1.0)

4.6.4 采用多表达式辅助定义约束和目标函数

同上一小节,只不过换成更为复杂的多个约束。

def constrs1_rule(model, i):
return model.e2[i] + model.x[i] <= 2
model.constrs1 = Constraint(model.I, rule = constrs1_rule) # model.I约束索引集合

5、求解

前面讲过 Pyomo 只能完成建模的任务,求解的还是需要将 Pyomo 的模型导入到专业的优化求解器来实现。如下代码就是调用 Gurobi 求解其来实现求解:

5.1 调用求解器

model = ConcreteModel()
model.I = Set(initialize = [i for i in range(4)])
model.J = Set(initialize = [i for i in range(4)])
model.x = Var(model.I, model.J, within = Reals, bounds = (0,1))
model.c = Param(model.I, model.J, initialize = {(1,1):2, (2,2):3}, default = 1)
def obj_rule(model):
return summation(model.c, model.x) # 定义目标函数
def constrs_rule1(model, i):
return sum([model.x[i,j] for j in model.J]) == 1 # 定义约束5.3
def constrs_rule2(model, j):
return sum([model.x[i,j] for i in model.I]) == 1 # 定义约束5.2 model.obj = Objective(rule=obj_rule, sense = minimize) # 设置优化目标,最小化目标函数
model.constrs1 = Constraint(model.I, rule = constrs_rule1)
model.constrs2 = Constraint(model.J, rule = constrs_rule2)
model.dual = Suffix(direction=Suffix.IMPORT) # 对偶变量定义
opt = SolverFactory('gurobi') # 指定 gurobi 作为求解器
# opt = SolverFactory('cplex') # 指定 cplex 作为求解器
# opt = SolverFactory('scip') # 指定 scip 作为求解器
solution = opt.solve(model) # 调用求解器求解

注意在调用求解器之前要确保求解器已经成功安装。Pyomo 目前支持的求解器种类也有很多种主要包括:Gurobi,Cplex,SCIP, CBC, Ipopt, BARON, Moske, Xpress, GLPK等等。调用方式和上面例子中的Gurobi 调用方式类似,只需要替换相关求解器的名字即可。

5.2 优化结果导出

在成功求解之后我们最常用的是将一些结果输出出来。一般最常用的是需要输出最优的目标函数值和最优的决策变量值,如下代码所示:

solution.write() # 写入求解结果
x_opt = np.array([value(model.x[i,j]) for i in model.I for j in model.J]).reshape((len(model.I), len(model.J))) # 提取最优解
obj_values = value(model.obj) # 提取目标函数
print("optimum point: \n {} ".format(x_opt))
print("optimal objective: {}".format(obj_values))

5.3 对偶变量值导出

记得如果需要使用对偶变量的话,需要在求解之前定义好对偶变量,例如 model.dual = Suffix(direction=Suffix.IMPORT) ,这样才能在求解完备之后采用下面的例子来遍历所需要的对偶变量的值:

for c in model.constrs1:
print(model.dual[model.constrs1[c]]) #遍历约束constrs1的对偶变量

5.4 求解状态查看

在求解完成之后,我们也可能需要查看求解的状态信息,可以通过如下变量体现:

print(solution.solver.termination_condition) # 终止条件 一般包括三种 optimal, feasible, infeasible
print(solution.solver.termination_message) # 求解得到的信息 一般为一行字符串信息
print(solution.solver.status) # 表示求解的状态 包括 ok, warning, error, aborted, or unknown

6、微电网日前优化调度实践

7、其他

pyo.Piecewise的离散约束方式

import numpy as np
import pyomo.environ as pyo
import matplotlib.pyplot as plt #Create macc
# logistic sigmoid function
def logistic(x, L=1, x_0=0, k=1):
return L / (1 + np.exp(-k * (x - x_0))) c = np.linspace(0,400,400)
macc = 2000*logistic(c,L=0.5,x_0 = 60,k=0.02)
macc = macc -macc[0] plt.rcParams['font.family'] = ['SimHei'] #
plt.figure(figsize=(10, 5))
plt.plot(c,macc,color='b')
plt.legend()
plt.show() s0 = 800
b0 = 1000
tnac0 = 100 cp0 = 10
ab0 = 100 model = pyo.ConcreteModel() #Declare variable
model.x = pyo.Var(domain=pyo.NonNegativeReals, bounds=(5,395), initialize = cp0)
model.y = pyo.Var()
model.piecewise = pyo.Piecewise(model.y, model.x, pw_pts=list(c), f_rule=list(macc), pw_constr_type='EQ', pw_repn='DCC') #Declare parameters
model.s = pyo.Param(domain=pyo.NonNegativeReals,initialize=s0)
model.b = pyo.Param(domain=pyo.NonNegativeReals,initialize=b0)
model.tnac = pyo.Param(domain=pyo.NonNegativeReals,initialize=tnac0) model.Obj = pyo.Objective(expr= model.b*model.x - model.y*model.x, sense=pyo.minimize) model.con1 = pyo.Constraint(expr=model.b - model.y <= model.tnac + model.s)
model.con2 = pyo.Constraint(expr=model.b - model.y >= 1)
model.con3 = pyo.Constraint(expr= model.y >= 0)
solver = pyo.SolverFactory('ipopt')
solver.solve(model, tee=True)

参考文献

【1】Pyomo 6.3.0 Documentation: https://pyomo.readthedocs.io/en/stable/

【2】Hart W E, Laird C D, Watson J P, et al. Pyomo-optimization modeling in python[M]. Berlin: Springer, 2017.

【3】https://jckantor.github.io/ND-P

Pyomo基础学习笔记:建模组成要素的编写方法的更多相关文章

  1. 【C#编程基础学习笔记】4---Convert类型转换

    2013/7/24 技术qq交流群:JavaDream:251572072  教程下载,在线交流:创梦IT社区:www.credream.com [C#编程基础学习笔记]4---Convert类型转换 ...

  2. 【C#编程基础学习笔记】6---变量的命名

    2013/7/24 技术qq交流群:JavaDream:251572072  教程下载,在线交流:创梦IT社区:www.credream.com [C#编程基础学习笔记]6---变量的命名 ----- ...

  3. 1.C#基础学习笔记3---C#字符串(转义符和内存存储无关)

    技术qq交流群:JavaDream:251572072  教程下载,在线交流:创梦IT社区:www.credream.com ------------------------------------- ...

  4. Java基础学习笔记总结

    Java基础学习笔记一 Java介绍 Java基础学习笔记二 Java基础语法之变量.数据类型 Java基础学习笔记三 Java基础语法之流程控制语句.循环 Java基础学习笔记四 Java基础语法之 ...

  5. Mysql数据库基础学习笔记

    Mysql数据库基础学习笔记 1.mysql查看当前登录的账户名以及数据库 一.单表查询 1.创建数据库yuzly,创建表fruits 创建表 ) ) ,) NOT NULL,PRIMARY KEY( ...

  6. 0003.5-20180422-自动化第四章-python基础学习笔记--脚本

    0003.5-20180422-自动化第四章-python基础学习笔记--脚本 1-shopping """ v = [ {"name": " ...

  7. Java基础学习笔记(一)

    Java基础学习笔记(一) Hello World 基础代码学习 代码编写基础结构 class :类,一个类即一个java代码,形成一个class文件,写于每个代码的前端(注意无大写字母) XxxYy ...

  8. C#RabbitMQ基础学习笔记

    RabbitMQ基础学习笔记(C#代码示例) 一.定义: MQ是MessageQueue,消息队列的简称(是流行的开源消息队列系统,利用erlang语言开发).MQ是一种应用程序对应用程序的通信方法. ...

  9. handlebars.js基础学习笔记

    最近在帮学校做个课程网站,就有人推荐用jquery+ajax+handlebars做网站前端,刚接触发现挺高大上的,于是就把一些基础学习笔记记录下来啦. 1.引用文件: jquery.js文件下载:h ...

  10. 基础学习笔记之opencv(6):实现将图片生成视频

    基础学习笔记之opencv(6):实现将图片生成视频 在做实验的过程中.难免会读视频中的图片用来处理,相反将处理好的图片又整理输出为一个视频文件也是非经常常使用的. 以下就来讲讲基于opencv的C+ ...

随机推荐

  1. 第十七篇:Django入门

    一.模板 二.BootStrap使用 三.web框架简绍 四.Django使用 五.创建APP 六.APP各目录功能 七.静态文件处理 八.模板语言 九.请求过程

  2. Vim 安装与基础操作指南

    0x00 链接 Vim 官网 Vim GitHub Vim 中文文档 0x01 准备 (1)下载与安装 在官网地址找到 Download 标签,在其中根据操作系统选择相应的版本,以下以 Windows ...

  3. 牛客网-SQL专项训练22

    ①在SQL中如何删除触发器:DROP TRIGGER 解析: 辨别:DROP TRIGGER 和 DELETE TRIGGER 删除触发器操作必须使用DROP语句进行,DELETE是删除行记录. ②请 ...

  4. HarmonyOS NEXT应用开发—验证码布局

    介绍 本示例介绍如何使用Text组件实现验证码场景,并禁用对内容的选中.复制.光标. 效果图预览 使用说明 单击组件可弹出输入法 在进行验证码输入时,无法对中间单个数字进行更改,无法选中输入内容,无光 ...

  5. 全链路灰度新功能:MSE 上线配置标签推送

    简介: 本文介绍了全链路灰度场景给配置管理带来的问题,介绍了 MSE 针对这一场景的解决方案,并通过实践的方式展示了配置标签推送的使用流程.后续,MSE 还会针对配置治理做更多的探索,帮助用户更好地解 ...

  6. 了解3D世界的黑魔法-纯Java构造一个简单的3D渲染引擎

    简介: 对于非渲染引擎相关工作的开发者来说,可能认为即使构建最简单的3D程序也非常困难,但事实上并非如此,本篇文章将通过简单的200多行的纯 Java代码,去实践正交投影.简单三角形光栅化.z缓冲(深 ...

  7. 跨全端SDK技术演进

    简介: 细想,团队进行跨平台开发已有三年有余,也是集团里面C++方向里比较早涉及该领域的部门之一,伴随业界跨平台技术发展与演进,我们也沉淀了一整套基于C++的跨平台技术体系,本文将以消息SDK为例,详 ...

  8. 工商银行分布式服务 C10K 场景解决方案

    简介: Dubbo 是一款轻量级的开源 Java 服务框架,是众多企业在建设分布式服务架构时的首选.中国工商银行自 2014 年开始探索分布式架构转型工作,基于开源 Dubbo 自主研发了分布式服务平 ...

  9. Serverless 应用优化四则秘诀

    ​简介:Serverless 架构下,虽然我们更多精力是关注我们的业务代码,但是实际上对于一些配置和成本也是需要进行关注的,并且在必要的时候,还需要根据配置与成本进行对我们的 Serverless 应 ...

  10. [FAQ] 对于 Puppeteer 和 Chromium 在 Linux 上的安装,需要安装哪些依赖库

      比如 puppeteer/chrome/linux-114.0.5735.133/chrome-linux64/chrome 到底要装哪些依赖. 一般根据报错提示,安装缺少的即可,以下是一般需要的 ...