背包问题高维线性规划解

背包问题是一个1896年提出的经典问题,在100余年的时间里出现了许多变种,而他最早的形式是01背包。
###大意是指背包容量V,有n个物体每个物体体积 V i V_i Vi,质量 M i M_i Mi,问在空间允许下,可装入物体的最大质量总和为多少.

不难贪心的想到当物体的密度越大时,他的效益也就越高,那么…
学过背包的朋友看到这里可能就要笑了,因为这个贪心明显是错的,但至于我为什么要提这个贪心,后面再说。
为了防止误导大家,我先讲一下01背包的正解:
####枚举:不难发现状态数只有 2 n 2^n 2n个,然后…
####动态规划:定义 d p i , j dp_{i,j} dpi,j为第放入i个物体,耗用j的空间的最大质量,O(Vn)即可做出来
ps:动态规划第二维可以滚动

#线性规划
看完正解之后,然后我来讲一讲背包问题的本质:
##背包问题本质是一个线性规划问题
##背包问题本质是一个线性规划问题
##背包问题本质是一个线性规划问题
重要的事说3遍。

关于线性规划,如果学过高中必修5,在不等式那一章有提到,其中的例题就是一个n=2的完全背包问题
如果没有学过必修5,也没有问题,线性规划是一个极易理解的方法。

不过,首先,你要确保你学过平面直角坐标系(-_-)///

对于平面上的一个点,我们可以用向量( x 0 x_0 x0, y 0 y_0 y0)来表示,
对于拓展到高维的情况,也可以用一个对应维度的向量表达:( t 0 t_0 t0, t 1 t_1 t1, t 2 t_2 t2,…, t n t_n tn)

对于平面上的一条直线我们可以很容易表示出起显函数表达式: y = a x + b y = ax + b y=ax+b
我们称这种形式为斜截式,这种形式对于斜率为正负无穷的直线无法表示
故在此引入直线的一般式: A x + B y + C = 0 Ax + By + C = 0 Ax+By+C=0,又称为直线方程
然后我们将其向三维推广
A x + B y + C z + D = 0 Ax+By+Cz+D=0 Ax+By+Cz+D=0

wait,不对啊,这个方程当x值确定为 x 0 x_0 x0时, B y + C z + ( A x 0 + D ) = 0 By+Cz+(Ax_0+D)=0 By+Cz+(Ax0+D)=0
这时,y与z的表达式为直线,那岂不是,对于每一个x的值,都有一个在y,z轴上的直线,
那是…
没错,你猜的没错,那就是平面,于是乎你得到了一个平面的表达式,
那向高维推广呢,
A 0 t 0 + A 1 t 1 + A 2 t 2 + . . . + A n t n + A n + 1 = 0 A_0t_0+A_1t_1+A_2t_2+...+A_nt_n+A_{n+1}=0 A0t0+A1t1+A2t2+...+Antn+An+1=0
这个方程可以描述一个(n-1)维的分割线,可以将一个n维物体分作两份。

看到这,你可能会说,说了半天,都没有扯到一点线性规划。
别急,这不是在打铺垫吗,你在仔细看看这句话:

一个(n-1)维的分割线,可以将一个n维物体分作两份。

对于一个直线(1维),可以将一个平面(2维)分割成两个半平面,
wait,是不是发现了什么,
被直线分割的两个半平面可以分别用两个二元不等式来表示:
A x + B y + C &lt; 0 Ax+By+C&lt;0 Ax+By+C<0
A x + B y + C &gt; 0 Ax+By+C&gt;0 Ax+By+C>0
如果放过来表示,那么这个二元不等式,也可以用半平面来表示,
那么二元不等式的组的解集,即可以用半平面交来表示,
那拓展到n维,岂不是:

一个n元不等式组的解集,可以用“n维物体”交,来表示

至于n维物体到底长啥样,我是想象不出来,但这种方法确实使得一些不等式问题变得形象起来。
那这种方法叫什么呢?

答:线性规划

那至于01背包问题,我们可以转化为以下不等式组
n i n_i ni表示第i个物品取几个
0 &lt; = v 1 n 1 + v 2 n 2 + v 3 n 3 + . . . + v n n n &lt; = V 0&lt;=v_1n_1+v_2n_2+v_3n_3+...+v_nn_n&lt;=V 0<=v1n1+v2n2+v3n3+...+vnnn<=V
0 &lt; = n i &lt; = 1     对 任 意 i 成 立 0&lt;=n_i&lt;=1 \ \ \ 对任意i成立 0<=ni<=1   i
不难发现这些不等式都可以转化成一个n维物体,这些物体的交,即为线性规划的可行域

wait,背包不是要求一个最大值吗,跟一个n维物体有什么关系。

我们先来写一下对于某一种选择情况 ( n 1 , n 2 , . . . , n n ) (n_1,n_2,...,n_n) (n1,n2,...,nn)的收益方程

w = m 1 n 1 + m 2 n 2 + m 3 n 3 + . . . + m n n n w=m_1n_1+m_2n_2+m_3n_3+...+m_nn_n w=m1n1+m2n2+m3n3+...+mnnn
转化为:
m 1 n 1 + m 2 n 2 + m 3 n 3 + . . . + m n n n − w = 0 m_1n_1+m_2n_2+m_3n_3+...+m_nn_n-w=0 m1n1+m2n2+m3n3+...+mnnnw=0
不难看出 n i n_i ni为自变量,这个方程即可转化为一个n-1维物体,就是可以将刚刚那个n维空间分成两份的东西
感性理解一波,即可发现,背包问题最优的解即为,那个n维凸包,在这个n-1维的斜率下的投影,
在可行域中最低的那个那个点.
那岂不是背包问题成为以一个凸包问题。
这个时候我们想一想刚开始我提的那个贪心算法,不正是沿着凸包的最优解吗?
这个时候,似乎整个世界都变得有些迷,那个贪心是对的吗?
但这个是时候,你就要仔细想想,背包问题,是一个,整数,问题
###整数,问题!
你似乎发现的整个事情的玄机,原来,贪心的错误在这里,那么线性规划如何解决背包问题,在此,我给出一个最暴力的方法扫描凸包旁的整点,O( ∏ i n ( V n i ) \prod^n_i(\frac{V}{n_i}) in(niV));似乎有点大,但是似乎也没有更好的解,却能让你更好的了解背包问题的本质。

然而线性规划的作用远不如此,更多用处还等大家慢慢探究.

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
高维线性规划是指在多维空间中,目标函数和约束条件都是非线性的情况下进行优化的问题。Python提供了多种库和工具来决这类问题,其中一种常用的库是SciPy。 SciPy是一个开源的科学计算库,其中包含了许多优化算法,可以用于高维线性规划问题。其中最常用的函数是`scipy.optimize.minimize`,它可以通过指定目标函数和约束条件来求最优。 在使用`scipy.optimize.minimize`函数时,需要定义目标函数和约束条件的函数,并将其作为参数传递给该函数。目标函数可以是任意的非线性函数,而约束条件可以是等式约束或不等式约束。 以下是一个简单的示例代码,演示了如何使用SciPy库来高维线性规划问题: ```python import numpy as np from scipy.optimize import minimize # 定义目标函数 def objective(x): return x**2 + x**2 # 定义约束条件 def constraint(x): return x + x - 1 # 定义初始猜测值 x0 = np.array([0, 0]) # 定义约束条件类型 constraint_type = {'type': 'eq', 'fun': constraint} # 使用 minimize 函数求最优 result = minimize(objective, x0, constraints=constraint_type) # 输出最优 print(result.x) ``` 在上述代码中,`objective`函数定义了目标函数,`constraint`函数定义了约束条件。`x0`是初始猜测值,`constraint_type`定义了约束条件的类型。最后使用`minimize`函数求最优,并输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值