【數學建模】儲藥柜的設計

2014高教社杯全國大學生數學建模競賽D題目

題目描述

儲藥柜的結構類似于書櫥,通常由若干個橫向隔板和豎向隔板將儲藥柜分割成若干個儲藥槽(如圖1所示)。為保證藥品分揀的準確率,防止發藥錯誤,一個儲藥槽內只能擺放同一種藥品。藥品在儲藥槽中的排列方式如圖2所示。藥品從后端放入,從前端取出。一個實際儲藥柜中藥品的擺放情況如圖3所示。
為保證藥品在儲藥槽內順利出入,要求藥盒與兩側豎向隔板之間、與上下兩層橫向隔板之間應留2mm的間隙,同時還要求藥盒在儲藥槽內推送過程中不會出現并排重疊、側翻或水平旋轉。在忽略橫向和豎向隔板厚度的情況下,建立數學模型,給出下面幾個問題的解決方案。

  1. 藥房內的盒裝藥品種類繁多,藥盒尺寸規格差異較大,附件1中給出了一些藥盒的規格。請利用附件1的數據,給出豎向隔板間距類型最少的儲藥柜設計方案,包括類型的數量和每種類型所對應的藥盒規格。
  2. 藥盒與兩側豎向隔板之間的間隙超出2mm的部分可視為寬度冗余。增加豎向隔板的間距類型數量可以有效地減少寬度冗余,但會增加儲藥柜的加工成本,同時降低了儲藥槽的適應能力。設計時希望總寬度冗余盡可能小,同時也希望間距的類型數量盡可能少。仍利用附件1的數據,給出合理的豎向隔板間距類型的數量以及每種類型對應的藥品編號。
  3. 考慮補藥的便利性,儲藥柜的寬度不超過2.5m、高度不超過2m,傳送裝置占用的高度為0.5m,即儲藥柜的最大允許有效高度為1.5m。藥盒與兩層橫向隔板之間的間隙超出2mm的部分可視為高度冗余,平面冗余=高度冗余×寬度冗余。在問題2計算結果的基礎上,確定儲藥柜橫向隔板間距的類型數量,使得儲藥柜的總平面冗余量盡可能地小,且橫向隔板間距的類型數量也盡可能地少。
  4. 附件2給出了每一種藥品編號對應的最大日需求量。在儲藥槽的長度為1.5m、每天僅集中補藥一次的情況下,請計算每一種藥品需要的儲藥槽個數。為保證藥房儲藥滿足需求,根據問題3中單個儲藥柜的規格,計算最少需要多少個儲藥柜。

提出關鍵點

一個儲藥槽內只能擺放同一種藥品。
要求藥盒與兩側豎向隔板之間、與上下兩層橫向隔板之間應留2mm的間隙,同時還要求藥盒在儲藥槽內推送過程中不會出現并排重疊、側翻或水平旋轉。在忽略橫向和豎向隔板厚度的情況下,建立數學模型。

建立數學模型

模型一:儲藥槽和藥盒關系模型

已知藥盒長寬高分別是 a , b , c a,b,c a,b,c毫米,設計儲藥槽長寬高分別是 x , y , z x,y,z x,y,z毫米。

要求藥盒在儲藥槽內推送過程中不會出現:

1.并排重疊 ,

即儲藥槽高度不能高于兩倍的藥盒高,儲藥槽寬度不能高于兩倍的藥盒寬
{ z < 2 c y < 2 b \begin{cases}z\lt 2c\\y \lt 2b\end{cases} {z<2cy<2b?

2.側翻,

在這里插入圖片描述

如上圖,紅色為藥盒,分兩種情況,情況一:綠色為儲藥槽;情況二:黑色為儲藥槽。

假設考慮的是不能完全側翻情況,那么模型為:
{ z < b 2 + c 2 + M ( 1 ? μ ) y < b 2 + c 2 + M ( 1 ? v ) μ + v ≥ 1 μ , v ∈ { 0 , 1 } \begin{cases} z\lt \sqrt{b^2+c^2} + M(1-\mu)\\ y \lt \sqrt{b^2+c^2} + M(1-v)\\ \mu + v \ge 1\\ \mu,v \in \set{0,1} \end{cases} ? ? ??z<b2+c2 ?+M(1?μ)y<b2+c2 ?+M(1?v)μ+v1μ,v{0,1}?
其中 M M M為定值,并且 M ≥ b 2 + c 2 M \ge \sqrt{b^2+c^2} Mb2+c2 ?

考慮實際情況,假設側翻角度超過 45 45 45度即為側翻
觀察上圖,下方綠線和紅線夾角為45度時為極限角度可以得到:
y = 2 2 ( a + b ) y = \dfrac{\sqrt{2}}{2}(a+b) y=22 ??(a+b)
并且側翻時側面解刨圖來看,長方形的一個點會和儲藥槽底部接觸,模擬物體旋轉過程發現當長方形的對角線和底部垂直時候,整個物體觸頂高度達到最高值。也就是說如果儲藥槽設計高度低于物體的對角線長度物體將無法側翻
可以得到模型:
{ z < b 2 + c 2 + M ( 1 ? μ ) y < 2 2 ( a + b ) + M ( 1 ? v ) μ + v ≥ 1 μ , v ∈ { 0 , 1 } \begin{cases} z\lt \sqrt{b^2+c^2} + M(1-\mu)\\ y \lt \dfrac{\sqrt{2}}{2}(a+b) + M(1-v)\\ \mu + v \ge 1\\ \mu,v \in \set{0,1} \end{cases} ? ? ??z<b2+c2 ?+M(1?μ)y<22 ??(a+b)+M(1?v)μ+v1μ,v{0,1}?
其中 M M M為定值,并且 M ≥ max ? ( b 2 + c 2 , 2 2 ( a + b ) ) M \ge \max{(\sqrt{b^2+c^2},\dfrac{\sqrt{2}}{2}(a+b))} Mmax(b2+c2 ?,22 ??(a+b))

將45度推廣為 α \alpha α度(準確來講是物體抬起的角度),模型將變為
{ z < b 2 + c 2 + M ( 1 ? μ ) y < b cos ? α + c cos ? ( π 2 ? α ) + M ( 1 ? v ) μ + v ≥ 1 μ , v ∈ { 0 , 1 } \begin{cases} z\lt \sqrt{b^2+c^2} + M(1-\mu)\\ y \lt b\cos{\alpha}+c\cos{(\dfrac{\pi}{2}-\alpha)} + M(1-v)\\ \mu + v \ge 1\\ \mu,v \in \set{0,1} \end{cases} ? ? ??z<b2+c2 ?+M(1?μ)y<bcosα+ccos(2π??α)+M(1?v)μ+v1μ,v{0,1}?
其中 M M M為定值,并且 M ≥ max ? ( b 2 + c 2 , b cos ? α + c cos ? ( π 2 ? α ) ) M \ge \max{(\sqrt{b^2+c^2},b\cos{\alpha}+c\cos{(\dfrac{\pi}{2}-\alpha)})} Mmax(b2+c2 ?,bcosα+ccos(2π??α))

3.水平旋轉 ,

實際上和側翻的情況一類似,只是寬和高變成了長和寬
設物體水平旋轉了 α \alpha α度就稱為水平旋轉了
y < b cos ? α + a cos ? ( π 2 ? α ) y \lt b\cos{\alpha}+a\cos{(\dfrac{\pi}{2}-\alpha)} y<bcosα+acos(2π??α)

要求藥盒與兩側豎向隔板之間、與上下兩層橫向隔板之間應留2mm的間隙

{ z ≥ c + 2 y ≥ b + 2 \begin{cases} z\ge c+2\\ y \ge b + 2 \end{cases} {zc+2yb+2?

建立解決問題的數學模型

問題一

假設已知所有盒裝藥品所需的儲藥槽寬度 x x x約束,和所有盒裝藥品總數 N N N
a i ≤ x i < b i , i = 1 , 2 , 3... N a_i\le x_i\lt b_i , i = 1,2,3...N ai?xi?<bi?,i=1,2,3...N

那么

解決模型一:

y j y_j yj?為第 j j j種豎向隔板間距類型大小
g i j g_{ij} gij?表示第 i i i種藥盒可不可以放進第 j j j種藥槽里面

{ min ? ∑ j = 1 M f j a i g i j ≤ y j f j < b i + M ′ ( 1 ? g i j ) ∑ j = 1 M g i j ≥ 1 f j , g i j ∈ { 0 , 1 } i = 1 , 2 , 3 , . . . N , j = 1 , 2 , 3 , . . . M \begin{cases} \min \displaystyle\sum_{j=1}^M f_j\\ a_ig_{ij} \le y_jf_j \lt b_i+M'(1-g_{ij})\\ \displaystyle\sum_{j=1}^M g_{ij} \ge 1\\ f_j , g_{ij} \in \set{0,1}\\ i = 1,2,3,...N , j = 1,2,3,...M \end{cases} ? ? ??minj=1M?fj?ai?gij?yj?fj?<bi?+M(1?gij?)j=1M?gij?1fj?,gij?{0,1}i=1,2,3,...N,j=1,2,3,...M?
M ′ ≥ max ? i = 1 N b i M'\ge \max_{i=1}^Nb_i Mmaxi=1N?bi?
這種模型就要先求出所有可能為豎向隔板間距類型的大小

解決模型二:

我們可以得出第 i i i種藥盒能放進的藥槽都得出來,記做 d i j d_{ij} dij?
如果 d i j = 1 d_{ij}=1 dij?=1表示得出第 i i i種藥盒能放進第 j j j種藥槽,反之不能
{ min ? ∑ j = 1 M f j ∑ j = 1 M d i j f j > 1 f j , g i j ∈ { 0 , 1 } i = 1 , 2 , 3 , . . . N , j = 1 , 2 , 3 , . . . M \begin{cases} \min \displaystyle\sum_{j=1}^M f_j\\ \displaystyle\sum_{j=1}^M d_{ij}f_j \gt 1\\ f_j , g_{ij} \in \set{0,1}\\ i = 1,2,3,...N , j = 1,2,3,...M \end{cases} ? ? ??minj=1M?fj?j=1M?dij?fj?>1fj?,gij?{0,1}i=1,2,3,...N,j=1,2,3,...M?

解決模型三:

{ a i g i ≤ x j < b i g i max ? ∑ i = 1 N g i f j , g i ∈ { 0 , 1 } i = 1 , 2 , 3 , . . . N , j = 1 , 2 , 3 , . . . M \begin{cases} a_ig_i \le x_j \lt b_ig_i\\ \max \displaystyle\sum_{i=1}^N g_i\\ f_j , g_i \in \set{0,1}\\ i = 1,2,3,...N , j = 1,2,3,...M \end{cases} ? ? ??ai?gi?xj?<bi?gi?maxi=1N?gi?fj?,gi?{0,1}i=1,2,3,...N,j=1,2,3,...M?
不斷增加 M M M的值,直到答案 ∑ i = 1 N g i ≥ N \displaystyle\sum_{i=1}^N g_i \ge N i=1N?gi?N,就求出其中一組解

問題二

簡單來說就是要求所有 藥盒與兩側豎向隔板之間的間隙超出2mm的部分 之和最小
利用上一問的模型三:
{ a i g i ≤ x j < b i g i max ? ∑ i = 1 N g i f j , g i ∈ { 0 , 1 } i = 1 , 2 , 3 , . . . N , j = 1 , 2 , 3 , . . . M \begin{cases} a_ig_i \le x_j \lt b_ig_i\\ \max \displaystyle\sum_{i=1}^N g_i\\ f_j , g_i \in \set{0,1}\\ i = 1,2,3,...N , j = 1,2,3,...M \end{cases} ? ? ??ai?gi?xj?<bi?gi?maxi=1N?gi?fj?,gi?{0,1}i=1,2,3,...N,j=1,2,3,...M?
其中 M M M的臨界值 M 1 M_1 M1?在問題一已經求出
所以就可以規定 M ≥ M 1 M\ge M_1 MM1?

同問題一的假設:
假設已知所有盒裝藥品所需的儲藥槽寬度 x x x約束,和所有盒裝藥品總數 N N N
a i ≤ x i < b i , i = 1 , 2 , 3... N a_i\le x_i\lt b_i , i = 1,2,3...N ai?xi?<bi?,i=1,2,3...N
觀察模型一:儲藥槽和藥盒關系模型中的所有約束條件,發現 a i a_i ai?只能是藥盒的寬度加兩毫米,為已知量
那么藥盒與兩側豎向隔板之間的間隙超出2mm的部分可以表示為:
x i ? a i x_i - a_i xi??ai?
因為還要約束兩側豎向隔板之間的間隙的種類,所以
m i n ∑ j = 1 M ∑ i = 1 N x j ? a i , x j ≥ a i min \displaystyle\sum_{j=1}^M\displaystyle\sum_{i=1}^N x_j-a_i , x_j\ge a_i minj=1M?i=1N?xj??ai?,xj?ai?
得到

模型一:

{ m i n ∑ j = 1 M ∑ i = 1 N x j ? a i , x j ≥ a i a i g i ≤ x j < b i g i ∑ i = 1 N g i = N f j , g i ∈ { 0 , 1 } i = 1 , 2 , 3 , . . . N , j = 1 , 2 , 3 , . . . M \begin{cases} min \displaystyle\sum_{j=1}^M\displaystyle\sum_{i=1}^N x_j-a_i , x_j\ge a_i\\ a_ig_i \le x_j \lt b_ig_i\\ \displaystyle\sum_{i=1}^N g_i = N\\ f_j , g_i \in \set{0,1}\\ i = 1,2,3,...N , j = 1,2,3,...M \end{cases} ? ? ??minj=1M?i=1N?xj??ai?,xj?ai?ai?gi?xj?<bi?gi?i=1N?gi?=Nfj?,gi?{0,1}i=1,2,3,...N,j=1,2,3,...M?

當然這種模型求解/優化都不容易
如果換個思路,在問題一已知有多少種兩側豎向隔板之間的間隙的種類了,并且求出了對應藥盒對應的兩側豎向隔板之間的間隙,那么就可以把兩側豎向隔板之間的間隙相同的都分為一組,最后形成 M M M組藥盒和對應的兩側豎向隔板之間的間隙

只需要每一組對應的兩側豎向隔板之間的間隙都取最小值,那么 M M M組加起來也就是所有 藥盒與兩側豎向隔板之間的間隙超出2mm的部分 之和最小

那么

模型二:

{ a i g i ≤ x j < b i g i ∑ i = 1 N g i = N a i k j ≤ x j < b i k j m i n ∑ i = 1 N x j ? a i k j , j = 1 , 2 , 3 , . . . M f j , g i , k j ∈ { 0 , 1 } i = 1 , 2 , 3 , . . . N , j = 1 , 2 , 3 , . . . M \begin{cases} a_ig_i \le x_j \lt b_ig_i\\ \displaystyle\sum_{i=1}^N g_i = N\\ a_ik_j \le x_j \lt b_ik_j\\ min \displaystyle\sum_{i=1}^N x_j-a_ik_j ,j = 1,2,3,...M\\ f_j , g_i , k_j\in \set{0,1}\\ i = 1,2,3,...N , j = 1,2,3,...M \end{cases} ? ? ??ai?gi?xj?<bi?gi?i=1N?gi?=Nai?kj?xj?<bi?kj?mini=1N?xj??ai?kj?,j=1,2,3,...Mfj?,gi?,kj?{0,1}i=1,2,3,...N,j=1,2,3,...M?

發現模型二實際上就是模型一的改進,模型二利用0/1變量 k j k_j kj?去定位藥盒所對應的兩側豎向隔板之間的間隙的同時也是在解決模型一中$ x_j\ge a_i$條件

由此就可以得到一個"通用"的解決手段:
如果出現當 x i ≤ a j x_i\le a_j xi?aj?時候某個式子 f ( x i , a j ) f(x_i,a_j) f(xi?,aj?)才執行/成立
f ( x i , a j ) , x i ≤ a j f(x_i,a_j) , x_i\le a_j f(xi?,aj?),xi?aj?
假設為 u = { f ( x i , a j ) , x i ≤ a j 0 , x i > a j u = \begin{cases}f(x_i,a_j) , x_i\le a_j\\0,x_i\gt a_j\end{cases} u={f(xi?,aj?),xi?aj?0,xi?>aj??
這時候引入一個0/1變量 k i k_i ki?
$ \begin{cases}u =f(x_i,a_jk_i)\x_i\le a_jk_j\end{cases}$
但要注意:
1. f ( x i , a j ) 改成 f ( x i , a j k i ) f(x_i,a_j)改成f(x_i,a_jk_i) f(xi?,aj?)改成f(xi?,aj?ki?)時候不能改變題目本意
2.之所以是 f ( x i , a j k i ) f(x_i,a_jk_i) f(xi?,aj?ki?)而不是 f ( x i , a j ) k i f(x_i,a_j)k_i f(xi?,aj?)ki?,是因為最好不出現決策變量和決策變量相乘
3.如果非要用 f ( x i , a j ) k i f(x_i,a_j)k_i f(xi?,aj?)ki?,需要將決策變量和決策變量相乘的模型重新轉化為線性模型

問題三

儲藥柜的寬度不超過2.5m、高度不超過2m,傳送裝置占用的高度為0.5m,即儲藥柜的最大允許有效高度為1.5m。
假設已知所有盒裝藥品所需的儲藥槽寬度 x x x約束,和所有盒裝藥品總數 N N N
a i < x i < b i , i = 1 , 2 , 3... N a_i\lt x_i\lt b_i , i = 1,2,3...N ai?<xi?<bi?,i=1,2,3...N
假設已知所有盒裝藥品所需的儲藥槽高度度 y y y約束,和所有盒裝藥品總數 N N N
c i < y i < d i , i = 1 , 2 , 3... N c_i\lt y_i\lt d_i , i = 1,2,3...N ci?<yi?<di?,i=1,2,3...N
則:
儲藥柜的寬度不超過2.5m
∑ i = 1 N x i ≤ 2500 \displaystyle\sum_{i=1}^N x_i \le 2500 i=1N?xi?2500
儲藥柜的最大允許有效高度為1.5m
∑ i = 1 N y i ≤ 1500 \displaystyle\sum_{i=1}^N y_i \le 1500 i=1N?yi?1500

在問題二中寬度冗余為 ∑ i = 1 N x j ? a i k j \displaystyle\sum_{i=1}^N x_j-a_ik_j i=1N?xj??ai?kj?
同理我們也可以得到高度冗余為 ∑ i = 1 N y j ? c i l j \displaystyle\sum_{i=1}^N y_j-c_il_j i=1N?yj??ci?lj?
平面冗余=高度冗余×寬度冗余
即平面冗余為 ( ∑ i = 1 N x j ? a i k j ) ( ∑ i = 1 N y j ? c i l j ) (\displaystyle\sum_{i=1}^N x_j-a_ik_j)(\displaystyle\sum_{i=1}^N y_j-c_il_j) (i=1N?xj??ai?kj?)(i=1N?yj??ci?lj?)

要使橫向隔板間距的類型數量也盡可能地少。我們可以利用問題一中的模型求出橫向隔板間距的類型數量臨界值 M 2 M_2 M2?

{ a i g i ≤ x j < b i g i ∑ i = 1 N g i = N c i o i ≤ y k < d i o i ∑ i = 1 N o i = N a i h j ≤ x j < b i h j a i l k ≤ y k < b i l k m i n ( ∑ i = 1 N x j ? a i h j ) ( ∑ i = 1 N y k ? c i l k ) , j = 1 , 2 , 3 , . . . M f j , g i , h j , o i , l k ∈ { 0 , 1 } i = 1 , 2 , 3 , . . . N , j = 1 , 2 , 3 , . . . M , k = 1 , 2 , 3 , . . . K \begin{cases} a_ig_i \le x_j \lt b_ig_i\\ \displaystyle\sum_{i=1}^N g_i = N\\ c_io_i\le y_k\lt d_io_i\\ \displaystyle\sum_{i=1}^N o_i = N\\ a_ih_j \le x_j \lt b_ih_j\\ a_il_k \le y_k \lt b_il_k\\ min (\displaystyle\sum_{i=1}^N x_j-a_ih_j)(\displaystyle\sum_{i=1}^N y_k-c_il_k) ,j = 1,2,3,...M\\ f_j , g_i , h_j , o_i ,l_k\in \set{0,1}\\ i = 1,2,3,...N , j = 1,2,3,...M ,k = 1,2,3,...K \end{cases} ? ? ??ai?gi?xj?<bi?gi?i=1N?gi?=Nci?oi?yk?<di?oi?i=1N?oi?=Nai?hj?xj?<bi?hj?ai?lk?yk?<bi?lk?min(i=1N?xj??ai?hj?)(i=1N?yk??ci?lk?),j=1,2,3,...Mfj?,gi?,hj?,oi?,lk?{0,1}i=1,2,3,...N,j=1,2,3,...M,k=1,2,3,...K?

問題四

已知第 i i i種藥品編號對應的最大日需求量為 e i e_i ei?和該藥盒長度為 z i z_i zi?毫米
在儲藥槽的長度為1.5m、每天僅集中補藥一次的情況下,計算每一種藥品需要的儲藥槽個數 x i x_i xi?.
2 ? 1500 e i ? z i ≤ x i \dfrac{2*1500}{e_i*z_i}\le x_i ei??zi?2?1500?xi?
這樣就得出了所有藥品對應所需儲藥槽個數 x i x_i xi?
在問題三中得出了一個藥柜中所有橫向(豎向)隔板間距的類型大小以及數量
同問題二從模型一到模型二的分組思路,每個藥品其實對應一個組別
可以得出第 i i i種藥品對應的組號 m i m_i mi?,并且也知道組號 m i m_i mi?對應的儲藥槽的個數 σ m i \sigma_{m_i} σmi??

假設有 M M M組, x j i x_{ji} xji?表示第 j j j組第 i i i種藥品對應所需儲藥槽個數, σ j \sigma_j σj?表示一個藥柜種組號 j j j對應的儲藥槽的個數。
得到問題模型:
m i n ( m a x j = 1 M ∑ i = 1 N j x j i σ j ) min(max_{j=1}^M \dfrac{\displaystyle\sum_{i=1}^{N_j} x_{ji}}{\sigma_j}) min(maxj=1M?σj?i=1Nj??xji??)

解決問題

問題一

模型一

在此之前已經初始化藥盒長寬高分別放進數組length,weight,height中
處理一下數據,得到模型一的 a i a_i ai? b i b_i bi?,并且得到 y j y_j yj?的所以可能取值
C++

void solve(){outFile.open("data.xlsx");if (!outFile.is_open()) {std::cerr << "無法打開文件" << std::endl;return ;}set<double>y;double a[N],b[N];for(int i=1;i<=1919;i++){a[i] = 2+weight[i];y.insert(a[i]);b[i] = min({2.0*weight[i],sqrt(weight[i]*weight[i] + height[i]*height[i]), sqrt(weight[i]*weight[i] + length[i]*length[i])});y.insert(b[i]);}for(int i=1;i<=1919;i++){outFile << a[i] << '\t';}outFile << '\n';for(int i=1;i<=1919;i++){outFile << b[i] << '\t';}outFile << '\n';for(auto x:y){outFile << x << '\t';}
}

這樣我們就完成了上面講的先求出所有可能為豎向隔板間距類型的大小

線性化:

void solve(){outFile.open("data.xlsx");if (!outFile.is_open()) {std::cerr << "無法打開文件" << std::endl;return ;}set<double>y;double a[N],b[N];for(int i=1;i<=1919;i++){a[i] = 2+weight[i];y.insert(a[i]);b[i] = min({2.0*weight[i],sqrt(weight[i]*weight[i] + height[i]*height[i]), sqrt(weight[i]*weight[i] + length[i]*length[i])});if((long long)b[i] == b[i])b[i]--;b[i] = (int)b[i];}for(int i=1;i<=1919;i++){outFile << a[i] << '\t';}outFile << '\n';for(int i=1;i<=1919;i++){outFile << b[i] << '\t';}outFile << '\n';cout << (int)y.size();for(auto x:y){outFile << x << '\t';}
}

解決模型一:

sets:aa/1..1919/:a,b;bb/1..47/:f,y;cc(aa,bb):g;
endsets
data:a=@ole("D:\homewrok\建模\儲藥柜的設計問題\data.xls",A1:BUU1);b=@ole("D:\homewrok\建模\儲藥柜的設計問題\data.xls",A2:BUU2);y=@ole("D:\homewrok\建模\儲藥柜的設計問題\data.xls",A3:AU3);
enddata
min=@sum(bb(j):f(j));
@for(aa(i):@for(bb(j):a(i)*g(i,j)<y(j)*f(j)));
@for(aa(i):@for(bb(j):b(i)+58*(1-g(i,j))>y(j)*f(j)));
@for(aa(i):@sum(bb(j):g(i,j))>1);
@for(cc(i,j):@bin(g(i,j)));
@for(bb(j):@bin(f(j)));

解得

  Global optimal solution found.Objective value:                              4.000000Objective bound:                              4.000000Infeasibilities:                              0.000000Extended solver steps:                               0Total solver iterations:                            13Variable           Value        Reduced CostF( 7)        1.000000            1.000000F( 22)        1.000000            1.000000F( 33)        1.000000            1.000000F( 47)        1.000000            1.000000

對應類型長度為:
18,33,44,58

模型二求解

C++預處理數據

void solve(){outFile.open("data2.xlsx");if (!outFile.is_open()) {std::cerr << "無法打開文件" << std::endl;return ;}double a[N],b[N];for(int i=1;i<=1919;i++){a[i] = 2+weight[i];b[i] = min({2.0*weight[i],sqrt(weight[i]*weight[i] + height[i]*height[i]), sqrt(weight[i]*weight[i] + length[i]*length[i])});b[i] = (int)(b[i]+0.5);}for(int i=1;i<=1919;i++){for(int j=12;j<=58;j++){int flag = a[i]<j&&j<b[i];outFile << flag << '\t';}outFile << '\n';}
}
sets:aa/1..1919/:;bb/1..47/:f;cc(aa,bb):d;
endsets
data:d = @ole("D:\homewrok\建模\儲藥柜的設計問題\data2.xls",A1:AU1919);
enddata
min=@sum(bb(j):f(j));
@for(aa(i):@sum(bb(j):d(i,j)*f(j))>1);
@for(bb(j):@bin(f(j)));

得到

  Global optimal solution found.Objective value:                              4.000000Objective bound:                              4.000000Infeasibilities:                              0.000000Extended solver steps:                               0Total solver iterations:                            58Variable           Value        Reduced CostF( 8)        1.000000            1.000000F( 23)        1.000000            1.000000F( 33)        1.000000            1.000000F( 47)        1.000000            1.000000

對應類型長度為:
19,34,44,58

純編程求解:

問題一轉換:給出1919個范圍 [ a i , b i ] [a_i,b_i] [ai?,bi?],問最少取多少個點使得每個范圍內至少有一個點

vector<pair<int,int>>v(1919);
void solve(){double a[N],b[N];for(int i=1;i<=1919;i++){a[i] = 2+weight[i];b[i] = min({2.0*weight[i],sqrt(weight[i]*weight[i] + height[i]*height[i]), sqrt(weight[i]*weight[i] + length[i]*length[i])});if((long long)b[i] == b[i])b[i]--;b[i] = (int)b[i];v[i-1].first = a[i]  , v[i-1].second=b[i];}
}
void solve2(){//貪心 每次未放入取上限最小的上限sort(v.begin(),v.end(),[&](pair<int,int> x, pair<int,int> y){if(x.first == y.first)return x.second < y.second;return x.first < y.first;});int cnt = 0 , start=0 , end;vector<pair<int,int>>ans;while(cnt < 1919){double x = v[start].second;cnt++;bool flag = false;for(int i=start;i<v.size();i++){if(v[i].first>x){end = i-1;flag = true;break;}}if(flag)ans.push_back(make_pair(v[end].first,x));else{ans.push_back(make_pair(v[v.size()-1].first,x));break;}start = end+1;}cout << cnt << '\n';//答案 4 個for(auto x:ans){cout << x.first << ',' << x.second << '\n';}
}

問題二轉換:給出1919個范圍 [ a i , b i ] [a_i,b_i] [ai?,bi?],給出最少取多少個點使得每個范圍內至少有一個點,求全部可能取值
注:不知道最小值為4,當新題做

vector<int>ans2;
int now_ans = 47;
int k=0;//不同取值種類數
int main() {solve();sort(v.begin(),v.end(),[&](pair<int,int> x, pair<int,int> y){if(x.first == y.first)return x.second < y.second;return x.first < y.first;});solve2_f(0,1);cout << k;return 0;
}
void solve2_f(int start ,  int cnt){if(cnt > now_ans)return ;for(int i = v[start].second;i>=v[start].first;i--){bool flag = false;for(int j=start;j<v.size();j++){if(v[j].first>i){flag = true;ans2.push_back(i);solve2_f(j,cnt+1);ans2.pop_back();break;}}if(!flag){ans2.push_back(i);for(auto x:ans2)cout << x << ' ';cout << '\n';ans2.pop_back();now_ans = min(now_ans,cnt);}}
}

問題二

純編程求解:

在上一個問題基礎上加個冗余計算即可

void solve2_f(int start ,  int cnt ,int rong){if(cnt > now_ans)return ;for(int i = v[start].second;i>=v[start].first;i--){bool flag = false;int sum = 0;for(int j=start;j<v.size();j++){if(v[j].first>i){flag = true;ans2.push_back(i);solve2_f(j,cnt+1,rong + sum);ans2.pop_back();break;}sum += i-v[j].first;}if(!flag){k++;ans2.push_back(i);for(auto x:ans2)cout << x << ' ';cout << "rong:" << rong;cout << '\n';ans2.pop_back();now_ans = min(now_ans,cnt);}}
}

求解得到最小的有

19 33 44 60 rong:10875
19 33 44 59 rong:10875
19 33 44 58 rong:10875

答案為19,33,44,58
因為最后一個取值沒有計算冗余度,明顯取58時候冗余度是最少的

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/14423.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/14423.shtml
英文地址,請注明出處:http://en.pswp.cn/web/14423.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python閉包探索,釋放函數記憶的秘術

引言 hello&#xff0c;大家好&#xff0c;我是一點&#xff0c;專注于Python編程&#xff0c;如果你也對感Python感興趣&#xff0c;歡迎關注交流。 希望可以持續更新一些有意思的文章&#xff0c;如果覺得還不錯&#xff0c;歡迎點贊關注&#xff0c;有啥想說的&#xff0c;可…

docker搭建gitlab及默認密碼修改及配置修改

推薦官方文檔 https://docs.gitlab.com/17.0/ee/install/docker.html 我使用的是docker run的方式&#xff0c;官方文檔后面有docker-compose、swarm、k8s的部署文檔 版本說明 1&#xff1a;可以部署gitlab-ce社區版和gitlab-ee企業版&#xff0c;然后&#xff0c;鑒于是個人…

Mysql總結2

Mysql慢優化 在mysql中&#xff0c;long_query_time的值為10&#xff0c;當sql語句執行的時間超過這個數值時&#xff0c;則會被記錄到慢查詢日志中。 Mysql語句查詢流程 1、客戶端發送sql語句到服務端&#xff1b; 2、服務端查看是否打開了緩存&#xff0c;若緩存打開&…

AIGC繪畫設計基礎-建筑設計應用

一、AI及AIGC 對于AI大家都不陌生&#xff0c;但是AIGC這個概念好多人其實不大清楚。“AI”是指人工智能技術本身&#xff0c;而“AIGC”是指基于人工智能技術而生成的內容。 生成式人工智能——AIGC&#xff08;Artificial Intelligence Generated Content&#xff09;&…

近鄰算法詳解

近鄰算法&#xff08;Nearest Neighbor Algorithm&#xff09;&#xff0c;也稱為K-近鄰算法&#xff08;K-Nearest Neighbors&#xff0c;KNN&#xff09;&#xff0c;是一種基本的分類和回歸方法。它的工作原理非常直觀&#xff1a;通過測量不同特征點之間的距離來進行預測。…

使用CommandLine庫創建.NET命令行應用

CommandLine是一個.NET庫&#xff0c;用于創建命令行應用程序。它提供了一種簡單的方法來解析命令行參數&#xff0c;并且可以幫助您構建一個功能強大的命令行界面。在本文中&#xff0c;我們將介紹如何使用CommandLine庫創建.NET命令行應用程序。 1. 背景 在.NET開發中&#…

SpringFramework實戰指南

二、SpringFramework實戰指南 目錄 一、技術體系結構 1.1 總體技術體系1.2 框架概念和理解 二、SpringFramework介紹 2.1 Spring 和 SpringFramework概念2.2 SpringFramework主要功能模塊2.3 SpringFramework 主要優勢 三、Spring IoC容器和核心概念 3.1 組件和組件管理概念3…

起底震網病毒的來龍去脈

2010年&#xff0c;震網病毒被發現&#xff0c;引起世界嘩然&#xff0c;在后續的10年間&#xff0c;陸陸續續有更多關于該病毒的背景和細節曝光。今年&#xff0c;《以色列時報》和《荷蘭日報》又披露了關于此事件的更多信息&#xff0c;基于這些信息&#xff0c;我們重新梳理…

優于InstantID!中山大學提出ConsistentID:可以僅使用單個圖像根據文本提示生成不同的個性化ID圖像

給定一些輸入ID的圖像&#xff0c;ConsistentID可以僅使用單個圖像根據文本提示生成不同的個性化ID圖像。效果看起來也是非常不錯。 相關鏈接 Code:https://github.com/JackAILab/ConsistentID Paper&#xff1a;https://ssugarwh.github.io/consistentid.github.io/arXiv.pd…

計算機畢業設計 | springboot養老院管理系統 老人社區管理(附源碼)

1&#xff0c;緒論 1.1 背景調研 養老院是集醫療、護理、康復、膳食、社工等服務服務于一體的綜合行養老院&#xff0c;經過我們前期的調查&#xff0c;院方大部分工作采用手工操作方式,會帶來工作效率過低&#xff0c;運營成本過大的問題。 院方可用合理的較少投入取得更好…

Python數據可視化(七)

繪制 3D 圖形 到目前為止&#xff0c;我們一直在討論有關 2D 圖形的繪制方法和繪制技術。3D 圖形也是數據可視化的 一個很重要的應用方面&#xff0c;我們接下來就重點講解有關 3D 圖形的實現方法。繪制 3D 圖形通常需要導 入 mpl_toolkits 包中的 mplot3d 包的相關模塊&#x…

三、Gazebo中實現機器人仿真(小白上手)+ubuntu18.04

接上一篇文章 1、\導航 vim .bashrc \先采用Nanocar嘗試導航 關閉終端&#xff1a;roslaunch robot_navigation gmapping.launch simulation:true rosrun teleop_twist_keyboard teleop_twist_keyboard.py 重啟終端&#xff1a; cd catkin_ws source ./devel/setu…

護網經驗面試題目原版

文章目錄 一、護網項目經驗1.項目經驗**Hvv的分組和流程**有沒有遇到過有意思的邏輯漏洞&#xff1f;有沒有自己開發過武器/工具&#xff1f;有做過代碼審計嗎&#xff1f;有0day嗎有cve/cnvd嗎&#xff1f;有src排名嗎&#xff1f;有沒有寫過技戰法有釣魚經歷嗎&#xff1f;具…

【數據結構】哈夫曼樹和哈夫曼編碼

一、哈夫曼樹 1.1 哈夫曼樹的概念 給定一個序列&#xff0c;將序列中的所有元素作為葉子節點構建一棵二叉樹&#xff0c;并使這棵樹的帶權路徑長度最小&#xff0c;那么我們就得到了一棵哈夫曼樹&#xff08;又稱最優二叉樹&#xff09; 接下來是名詞解釋&#xff1a; 權&a…

VC++位移操作>>和<<以及邏輯驅動器插拔產生的掩碼dbv.dbcv_unitmask進行分析的相關代碼

VC位移操作>>和<<以及邏輯驅動器插拔產生的掩碼dbv.dbcv_unitmask進行分析的相關代碼 一、VC位移操作符<<和>>1、右位移操作符 >>&#xff1a;2、左位移操作符 <<&#xff1a; 二、邏輯驅動器插拔產生的掩碼 dbv.dbcv_unitmask 進行分析的…

如何使用Suno:免費的AI歌曲生成器

文章目錄 Suno AI 是什么&#xff1f;Suno AI 如何工作&#xff1f;選擇Suno AI的理由&#xff1a;核心優勢易于操作多樣化創作靈活的定價策略版權保障技術突破 如何使用Suno AI創作歌曲&#xff1f;第1步&#xff1a;注冊Suno AI賬戶第2步&#xff1a;輸入提示詞創建第 3 步&a…

作業-day-240522

思維導圖 使用IO多路復用實現并發 select實現TCP服務器端 #include <myhead.h>#define SER_IP "192.168.125.112" #define SER_PORT 8888int main(int argc, const char *argv[]) {int sfdsocket(AF_INET,SOCK_STREAM,0);if(sfd -1){perror("socket er…

脆皮之“字符函數與字符串函數”寶典

hello&#xff0c;大家好呀&#xff0c;感覺我之前有偷偷摸魚了&#xff0c;今天又開始學習啦。加油&#xff01;&#xff01;&#xff01; 文章目錄 1. 字符分類函數2. 字符轉換函數3. strlen的使用和模擬實現3.1 strlen 的使用3.1 strlen 的模擬1.計算器方法2.指針-指針的方…

Python的shutil模塊探索,文件操作的瑞士軍刀

hello&#xff0c;大家好&#xff0c;我是一點&#xff0c;專注于Python編程&#xff0c;如果你也對感Python感興趣&#xff0c;歡迎關注交流。 希望可以持續更新一些有意思的文章&#xff0c;如果覺得還不錯&#xff0c;歡迎點贊關注&#xff0c;有啥想說的&#xff0c;可以留…