CPLEX雜記(四) 松約束與緊約束

松約束和緊約束是針對不等式約束而言的,如果在一個解中侣签,不等式約束左端項(xiàng)的值和右端項(xiàng)的值相等塘装,那么它就是一個緊約束;反之影所,則是一個松約束蹦肴。

在運(yùn)籌學(xué)的問題建模與求解中,約束的放松收緊是調(diào)節(jié)可行域的重要手段猴娩。

在CPLEX求解問題后阴幌,我們有時候想要知道在得到的解中,哪些約束是緊約束卷中,哪些約束是松約束矛双。

下面我們就用一個例子來看一下如何在CPLEX中查看對某個解,某個約束是否是緊約束蟆豫。

問題描述

這里用清華大學(xué)出版社的運(yùn)籌學(xué)第四版第106頁的運(yùn)輸問題舉個例子:

某公司有三個加工廠议忽,生產(chǎn)同一種產(chǎn)品。它的主要銷售地有4個十减,從每個工廠出發(fā)栈幸,到銷售地的單位運(yùn)價如下表所示愤估,單位為元/噸:

銷售地B1 銷售地B2 銷售地B3 銷售地B4
工廠A1 16 13 22 17
工廠A2 14 13 19 15
工廠A3 19 20 23 -

而三個工廠的每日產(chǎn)量分別為50,60速址,50噸玩焰。每個銷售地的每日最小需求量為30,70芍锚,0震捣,10噸;每日最大需求量為50闹炉,70蒿赢,30,不限渣触。

求出總運(yùn)費(fèi)最節(jié)省的產(chǎn)品運(yùn)輸方案羡棵。

模型

# 導(dǎo)入包
from docplex.mp.model import Model
import numpy as np

# 創(chuàng)建數(shù)據(jù)
n_factory: int = 3
n_market: int = 4
I: list = list(range(n_factory)) # 工廠下標(biāo)的集合
J: list = list(range(n_market)) # 銷售地下標(biāo)的集合
bigM: int = 1000 # 大M
# 設(shè)置單位運(yùn)費(fèi)
cost_mat = [[16, 13, 22, 17],
            [14, 13, 19, 15],
            [19, 20, 23, bigM]]
min_demand: list = [30, 70, 0, 10] # 最小需求
max_demand: list = [50, 70, 30, bigM] # 最大需求
supply: list = [50, 60, 50] # 工廠的每日產(chǎn)量
  
# 建立模型
mdl = Model("Transportation Problem", cts_by_name = True)
x = mdl.continuous_var_dict([(i, j) for i in I for j in J], name = "volume")

# 設(shè)定目標(biāo)函數(shù) - 總的運(yùn)送成本最低
mdl.minimize(mdl.sum(cost_mat[i][j] * x[(i, j)] for i in I for j in J))

# 添加約束
# 1. 所有工廠產(chǎn)量都要運(yùn)送出去
mdl.add_constraints((mdl.sum(x[(i,j)] for j in J) == supply[i] for i in I), names="SupplyAmountConstraint")
# 2. 每個銷售地得到的總量介于最小需求和最大需求之間
mdl.add_constraints((mdl.sum(x[(i,j)] for i in I) <= max_demand[j] for j in J), names="MaxDemandConstraint")
mdl.add_constraints((mdl.sum(x[(i,j)] for i in I) >= min_demand[j] for j in J), names="MinDemandConstraint")

# 求解
sol = mdl.solve()

# 輸出結(jié)果
print(sol.as_df())

可以得到這個問題的解:

         name  value
0  volume_0_1   50.0
1  volume_1_1   20.0
2  volume_1_3   40.0
3  volume_2_0   50.0

也就是說,工廠A1運(yùn)送到銷售地B2的量為50噸嗅钻,工廠A2運(yùn)送到銷售地B2的量為20噸皂冰,運(yùn)送到銷售地B3的量為40噸,工廠A3運(yùn)送到銷售地B1的量為50噸時养篓,總運(yùn)輸費(fèi)用最低秃流。

查看緊約束

在CPLEX中并沒有原生函數(shù)能幫我們查看一個約束是緊約束還是松約束,這里我們可以間接實(shí)現(xiàn)松緊約束的判斷:

對每個不等式約束的左端項(xiàng)和右端項(xiàng)進(jìn)行求值柳弄,然后判定是否相等舶胀。

如果相等,則為緊約束碧注,否則為松約束嚣伐。

from docplex.mp.constants import ComparisonType
# 查看哪些約束是緊約束
tol: float = 1e-5
for ct in mdl.iter_constraints():
    # 跳過等式約束
    if ct.sense == ComparisonType.EQ:
        continue
    print("-----------------")
    print("約束名: {}".format(ct.name))
    lhs: float = sol.get_value(ct.get_left_expr())
    rhs: float = sol.get_value(ct.get_right_expr())
    print("左端項(xiàng): {}".format(lhs))
    print("右端項(xiàng): {}".format(rhs))
    if abs(lhs - rhs) < tol:
        print("緊約束")
    else:
        print("松約束")

得到如下結(jié)果,可以看到我們只保留了不等式約束萍丐,其中

-----------------
約束名: MaxDemandConstraint1
左端項(xiàng): 50.0
右端項(xiàng): 50
緊約束
-----------------
約束名: MaxDemandConstraint2
左端項(xiàng): 70.0
右端項(xiàng): 70
緊約束
-----------------
約束名: MaxDemandConstraint3
左端項(xiàng): 0
右端項(xiàng): 30
松約束
-----------------
約束名: MaxDemandConstraint4
左端項(xiàng): 40.0
右端項(xiàng): 1000
松約束
-----------------
約束名: MinDemandConstraint1
左端項(xiàng): 50.0
右端項(xiàng): 30
松約束
-----------------
約束名: MinDemandConstraint2
左端項(xiàng): 70.0
右端項(xiàng): 70
緊約束
-----------------
約束名: MinDemandConstraint3
左端項(xiàng): 0
右端項(xiàng): 0
緊約束
-----------------
約束名: MinDemandConstraint4
左端項(xiàng): 40.0
右端項(xiàng): 10
松約束
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末轩端,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子逝变,更是在濱河造成了極大的恐慌基茵,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壳影,死亡現(xiàn)場離奇詭異拱层,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)态贤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門舱呻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事箱吕〗娌担” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵茬高,是天一觀的道長兆旬。 經(jīng)常有香客問我,道長怎栽,這世上最難降的妖魔是什么丽猬? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮熏瞄,結(jié)果婚禮上脚祟,老公的妹妹穿的比我還像新娘。我一直安慰自己强饮,他們只是感情好由桌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著邮丰,像睡著了一般行您。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上剪廉,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天娃循,我揣著相機(jī)與錄音,去河邊找鬼斗蒋。 笑死捌斧,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吹泡。 我是一名探鬼主播骤星,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼爆哑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起舆吮,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤揭朝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后色冀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體潭袱,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年锋恬,在試婚紗的時候發(fā)現(xiàn)自己被綠了屯换。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖彤悔,靈堂內(nèi)的尸體忽然破棺而出嘉抓,到底是詐尸還是另有隱情,我是刑警寧澤晕窑,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布抑片,位于F島的核電站,受9級特大地震影響杨赤,放射性物質(zhì)發(fā)生泄漏敞斋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一疾牲、第九天 我趴在偏房一處隱蔽的房頂上張望植捎。 院中可真熱鬧,春花似錦阳柔、人聲如沸焰枢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽医咨。三九已至,卻和暖如春架诞,著一層夾襖步出監(jiān)牢的瞬間拟淮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工谴忧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留很泊,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓沾谓,卻偏偏與公主長得像委造,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子均驶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 本文介紹如何用數(shù)學(xué)語言對實(shí)際中的優(yōu)化問題進(jìn)行建模. 通過建立數(shù)學(xué)模型, 我們利用現(xiàn)成的求解器可以便捷地計算出最優(yōu)解...
    胡拉哥閱讀 675評論 1 0
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險厭惡者昏兆,不喜歡去冒險,但是人生放棄了冒險妇穴,也就放棄了無數(shù)的可能爬虱。 ...
    yichen大刀閱讀 6,054評論 0 4
  • 公元:2019年11月28日19時42分農(nóng)歷:二零一九年 十一月 初三日 戌時干支:己亥乙亥己巳甲戌當(dāng)月節(jié)氣:立冬...
    石放閱讀 6,882評論 0 2