依據運籌學建模,主要介紹變數和約束
參考文獻:
這篇文獻是ibm在constraint期刊發表的cpo模組介紹,更加詳細,本文只是對其進行了摘要和翻譯,想要更全面的了解cp模組,可以檢視此文獻。
後續會對docplex的cp模組進行介紹,但基本內容都是關於區間變數和關係約束這兩塊。
區間變數表示排程中佔據一段時間的活動或者任務,並且其在排程問題中的時間位置是不確定的,也就是不知道任務是在什麼時候開始。
區間變數由開始時間和結束時間組成。並且區間變數是可選的,也就是我們設定的區間變數可能在解**現,也可以不出現。
所以可以應用於以下場景:
可選任務:任務未必一定全部加工
備選資源,但這些資源並非全部使用,而是選擇一部分
模式選擇:任務有多種工作模式,但只能選乙個
可選路徑:任務的加工過程有多個,但只選擇一條
hierarchical description of a project as a work-breakdown structure with tasks decomposed
into sub-tasks, part of the project being optional
例如區間變數a是乙個決策變數,其值域可以為空集,也可以為[s,e],s表示開始時間,e表示結束時間,l=s-e,表示其長度
值得注意的是,區間變數有乙個和長度length相聯絡的屬性size,size是小於等於length的。
如果區間變數a為空集,其相當於不存在,即便應用在後面的nooverlap函式或者次序約束上,都相當於沒有作用
# 區間變數a表示值域為預設的,也就是l不確定,但s和e必須為非負數,此時的size和length相等
dvar interval a;
# b則表示其區間長度在【0,10】的範圍內
dvar interval b size 0..10;
# c表示區間變數為可選,並且長度為10,可以從-1000開始到1000
dvar interval c optional in -1000..1000 size 10;
比如有100個任務,每個工序都有乙個加工時間time,那麼這些工序應該設定為
dvar interval task[i in tasks] optional in 0..100 size time[i];
tasks表示所有的任務都只能在0到100內進行,time表示所有任務的加工時間,也就是size。
option表示任務是可選的,也就是可以任務不是必然存在。
這部分主要是介紹隨著時間的變化,可以對區間變數的length進行變化,例如變大或縮小,主要是通過設定函式,我沒有用過,因此不再介紹。
這裡表示的是邏輯約束,也就是if條件的問題,具體可以看下面兩個
presenceof()
函式表示的是如果區間變數存在則返回1,否則返回0
# 表示如果a是數,則b一定是實數
presenceof(a) => presenceof(b)
# a,b同時為present或者同時為absent
presenceof(a) == presenceof(b)
這裡主要說的是區間變數之間的關係,比如任務a和任務b之間的開始和結束時間的關係
startof(a) 任務a開始的時間
endof(b) 任務a結束的時間
endbeforeend(a,b) 任務a結束的時間大於任務b結束的時間
可以開始開始,結束結束,開始結束,結束開始等關係
# a的完工時間必須在b開始之間的z個單位
endbeforestart(a,b,z)
# 其中z可以為負值,表示推遲到b開始之後的z個單位,a才完工
# z也可以為固定的值或者決策變數
單個區間變數和一組區間變數之間的關係
跨越約束
span(a,)
表示區間邊變數a,如果存在,將分布在區間變數集合b=中。也就是區間變數a和b集合第乙個存在的元素一起開始,和最後乙個存在的元素一起結束
舉個例子:汽車產品加工中有許多任務序,那這些工序有些是存在的,有些可能是冗餘的,那汽車可以設定為乙個區間變數,其基本屬性是[start,end]時間,而組成汽車產品的工序也可以設定為區間變數。
我們如何確認汽車的基本屬性呢?
使用span約束可以表達,汽車的完工時間應該在任務區間變數的範圍內。也就是乙個汽車的區間變數一定位於這一組工序的區間變數中,但是具體的位置不知道,只知道汽車區間變數可以出現在這組工序區間變數的任意位置。
span(汽車,一組工序),就能夠表達
候選變數,區間變數a是從集合b中任意選擇乙個
alternative(a,,c)
如果a存在,則其將與b集合中選中的某個元素一起開始和結束,c則會和a一起開始和結束
大多數排程任務中都會存在一些分離資源(disjunctive resources),其在任何時間點只能完成一項任務,典型的例子如工人,機器等。因此設計了乙個新的決策變數 sequence variable,其值是一系列區間變數的排列。用來表示這些區間變數之間的一些關係
舉個例子:乙個產品有5個工序,工序加工的先後順序就是這個約束的含義,形如p=[2,1,3,5,4],任務2和任務1的關係就是
before(p,2,1)
在序列p中,任務2在任務1前
# 如果a存在,則其在序列p中的位置為第乙個
first(p,a)
# 如果a存在,則其在序列p中的位置為最後乙個
last(p,a)
# 如果a,b都存在,則在p中的位置表現為,a在b的前面
before(p,a,b)
# 如果a,b都存在,則在p中,a在b的前面,且直接相鄰,中間沒有其他區間變數
prev(p,a,b)
排序約束並不決定區間變數的開始時間和結束時間,其只是確定相對位置,進行合理分配。無交叉約束表示的是,兩個任務之間不存在交叉區域,比如一組區間變數a,其中任務2的開始和結束時間分別是3和5,則任務1的開始和結束時間就不能是3和5。
nooverlap(a)
例如有兩組排序p1和p2,已經獲得了p1內部區間變數之間的關係,可以直接使用samesequence(p1,p2),將這種關係轉給p2,具體以後補充。
約束規劃中的基礎變數是區間變數,基礎約束是次序約束和排序約束
只需要明白interval variable、sequence variable、temporal constraint、sequence constraint這四部分的內容,一般的排程問題都能構建出來。
CPLEX 解決大規模計算 變數 約束 新增方法
新增變數思路 add var xx ilomodel f model,ilonumvararray f var,ilorangearray f cons,data input f data 新增變數 新增約束條件思路 add con dtm powerbalance ilomodel f model...
Mysql建表約束
2.自增約束 3.唯一約束 4.非空約束 5.預設約束 6.外來鍵約束 7.檢查約束 無效 8.列舉型別約束 9.觸發器 trigger 約束 1.主鍵約束 它是能夠唯一確定一張表中的一條記錄,也就是我們通過給某個字段新增約束,也就是使得改字段不重複而且不為空 1.1 普通主鍵約束 create t...
MySQL建表約束
它能夠唯一確定一張表中的記錄,也就是我們通過給某個字段新增約束,就可以使得該字段不重複且不為空。create table user id int primary key,name varchar 20 insert into user values 1,張三 唯一 不能再次插入id 1的記錄 資料 ...