整数规划和0-1规划
在规划问题中,有些最优解可能不是整数,但对于某些具体问题,常要求某些变量的解必须是整数,例如机器台数。
为了满足整数的要求,直接把已得的非整数解化整不一定是可行解和最优解,所以应该有特殊的方法来求解整数规划。
在整数规划中,如果所有变量都限制为整数,则称为纯整数规划;如果仅一部分变量限制为整数,则称为混合整数规划。整数规划的一种特殊情形是0-1规划,仅限于0或1。
- 对于整数线性规划,可以用计算机求解(在线性规划的基础上,加入决策变量取整数的条件)
- 对于整数非线性规划,无特定算法,只能用近似算法,比如蒙特卡洛等。
整数线性规划的Python代码实例(匈牙利算法)
这个算法用于解决指派问题,其中每个元素都有一个相关的成本或权重,任务是找到一种分配方式,使得总成本最小。
from scipy.optimize import linear_sum_assignment
# 导入SciPy库中的linear_sum_assignment函数,该函数用于解决线性和二次分配问题。
import numpy as np
cost = np.array([[4, 1, 3], [2, 0, 5], [3, 2, 2]])
# 创建一个NumPy数组cost,表示一个成本矩阵,其中的数字代表了各个任务的成本。
row_ind, col_ind = linear_sum_assignment(cost)
# 使用linear_sum_assignment函数解决最小权匹配问题,返回最优的行索引和列索引。
# row_ind是行的索引,col_ind是对应行的最优指派的列索引。
print(row_ind) # 开销矩阵对应的行索引
print(col_ind) # 对应行索引的最优指派的列索引
print(cost[row_ind, col_ind]) # 提取每个行索引的最优指派列索引所在的元素,形成数组
# 这里表示每个任务的最小成本。
print(cost[row_ind, col_ind].sum()) # 数组求和
# 打印上述数组的总和,即最优指派的总成本。
整数非线性规划的蒙特卡洛模拟Python代码
import numpy as np
def check(x):
if x.sum() > 400:
return False
if x[0] + 2 * x[1] + 2 * x[2] + x[3] + 6 * x[4] > 800:
return False
if 2 * x[0] + x[1] + 6 * x[2] > 200:
return False
if x[2] + x[3] + 5 * x[3] > 200:
return False
return True
# 定义一个名为check的函数,接受一个NumPy数组x作为参数。
# 该函数检查数组x的元素是否满足约束条件。
def get_radom():
x = np.random.randint(100, size=5)
while not check(x):
x = get_radom()
return x
# 定义一个名为get_radom的函数,生成一个包含五个元素、取值在0到99之间的随机NumPy数组。
# 该函数会持续生成数组,直到满足check函数的条件为止,然后返回该数组。
lim = 10 ** 5
ans = -1
# 设定变量lim为100万,初始化变量ans为-1。
for i in range(lim):
num = get_radom()
ans = max(ans, np.max(num))
if i % 10000 == 0:
print(i)
# 开始一个循环,迭代lim次。在每次迭代中,生成一个随机数组num,
# 然后将ans更新为当前ans与num.all()的最大值。每隔1万次迭代,打印当前的迭代次数i。
print('ans=%d' % ans)