2011-03-25 111 views
3

我有一個整數編程問題。我有一根10米長的管子。我想盡可能多地切出1.2毫米的碎片,然後用100毫米的碎片切割剩餘的管道。我必須離開100mm才能抓住機器。我如何在mathematica中對此進行優化?我可以把它解決爲一個平等的猜測,但如果我只是想直接回答這個問題。 基本上,儘可能多的y,然後x:es。Mathematica中的整數優化?

Maximize[{x*100+y*1200, x*100+y*1200<9900},{x,y},Integers]只是給我一個不平等的情節。 是的,我檢查了wolfram的指示。

+0

你使用的是什麼版本? – rcollyer 2011-03-26 02:39:03

+0

最大化[{y,{x * 100 + y * 1200 == 9900,x> = 0,y> = 0}},{x,y},Integers] – 2011-03-28 15:15:16

回答

1

使用假設上x,y等是>0 etc,你將最終能夠得到一個值與//N

數學犯規假設你是在現實世界中!

+0

Maximize [{x * 99 + y * 1200,{x * 99 + y * 1200 <4900,x> 0,y> 0}},y,Integers]也不起作用。 – johnny 2011-03-26 00:39:05

+0

@johnny第二個參數必須指定所有變量。 – 2011-03-28 15:13:48

3

由於9900和1200是兩個100的倍數,該算法只是

TotLen = 9900; 
numberOf1200pieces = IntegerPart[TotLen/1200]; 
numberOf100pieces = IntegerPart[(TotLen - 1200 numberOf1200pieces)/100]; 

Print["Number of 1200mm pieces: ", numberOf1200pieces]; 
Print["Number of 100mm pieces: ", numberOf100pieces]; 
Print["Leftover: ", 9900 - numberOf1200pieces 1200 - numberOf100pieces 100,"mm"]; 

Number of 1200mm pieces: 8 
Number of 100mm pieces: 3 
Leftover: 0mm 

你也可以嘗試:

Maximize[{x*100 + y*1200, x*100 + y*1200 == 9900}, {x, y}, Integers] 
->{9900, {x -> 3, y -> 8}} 
1

貝利薩留的solution是通過Maximize最簡單的方法。但是,它要求將不平等變爲平等,這並不反映你的意圖。相反,使用五,七,我會添加第二個條件

Maximize[{x*100 + y*1200, x*100 + y*1200 <= 9900, y > x > 0}, 
     {x, y}, Integers] -> {9900, {y -> 8, x -> 3}} 

新的條件(y > x > 0)反映了你的意圖,較大件先選擇好。此外,請注意,我將您的分部出現在9900之間,將不等式(<)更改爲<=

+0

在我的機器中你的eq。給出'{9900,{x - > 3,y - > 8}}' – 2011-03-26 03:24:47

+0

我正在用'<'而不是'<='給出'x-> 2'而不是代碼給出的內容。 :P – rcollyer 2011-03-26 03:43:28

+0

這很好,但取決於係數,它仍然可能不完美。有沒有辦法指定一個雙重最大化,其中y儘可能大? – 2011-03-26 03:47:55

1

要回答面值的簡單問題,而不是推斷它是一個玩具優化的例子,下面是一個「統一」數字的方法。

Floor[ FoldList[Mod, #, [email protected]#2]/#2 ] &[ 9900, {1200, 100} ] 

應對貝利薩留暗示,即我的回答是太天真,我覺得這可能是更復雜的情況下,有效的,雖然低效的方法。考慮分拆成9950的長度12,75,和1200

i = 9950; 

While[x = [email protected][i--, All, {12, 75, 1200}, 1]; x === {}] 

x[[1]] // Tally 
+0

通常的問題是更微妙一點,因爲你不想吃剩飯。假設你有[16,{5,3}]作爲輸入。作爲結果,您可以給予{3,0}或{2,2}。最後一個沒有剩飯。一般情況是一個很好研究的問題,並且有很多商業產品。幾乎每個工廠在某個生產階段都有這種問題。 – 2011-03-26 21:58:35

+0

@belisarius這是OP可能想要解決的更深層次的問題,我希望看到使用Mathematica的解決方案。儘管如此,問題仍然存在:「我想盡可能多地切出1.2毫米的碎片,然後用100毫米的碎片切割剩餘的管道。」我認爲我的幼稚代碼可以做到這一點。我錯了嗎? – 2011-03-26 23:17:30

+0

啊,你今天太敏感了:)!我只是在試圖說明,當你添加一些簡單的約束時,問題變得很奇怪,更不用說在現實世界中。也許我的堅持來自多年前,當時我參與解決了艾弗裏的一個大型捲紙切割場所的相同問題。這是一個相當的項目。如果我以任何方式進攻,請接受我的道歉,因爲那不是我的意圖。 – 2011-03-27 00:07:16

0
decideOrderOfProduction[itemsToProduce_] := 
Map[#[[1]] &, Sort[itemsToProduce, #1[[2]] > #2[[2]] &]] 
minimizeWaste[pipe1_, pipe2_] := { 
    Maximize[{pipe1*x + pipe2*y, pipe1*x + pipe2*y <= 4900, 
    y >= x >= 0}, {x, y}, Integers] 
    } 
minimizeWaste[pipe_] := { 
    Maximize[{pipe*x, pipe*x <= 4900, x >= 0}, x, Integers] 
    } 
planProduction[itemsToProduce_] := { 
    productionOrder = decideOrderOfProduction[itemsToProduce]; 
    strategy = {}; 
    While[Length[productionOrder] >= 2, 
    pipe1 = productionOrder[[1]]; 
    pipe2 = productionOrder[[2]]; 
    strategy = 
    Append[strategy, {pipe1, pipe2, minimizeWaste[pipe1, pipe2]}]; 
    productionOrder = Drop[productionOrder, 2];]; 
    If[Length[productionOrder] == 1, 
    strategy = 
    Append[strategy, {productionOrder[[1]], Null, 
     minimizeWaste[productionOrder[[1]]]}]]; 
    strategy 
    } 


items = {{99, 1}, {200, 12}, {1200, 2}, {90, 5}, {70, 1200}}; 
decideOrderOfProduction[items] 
planProduction[items] 
 
{70, 200, 90, 1200, 99} 

{{{70, 200, {{4900, {x -> 10, y -> 21}}}}, {90, 
    1200, {{4890, {x -> 1, y -> 4}}}}, {99, 
    Null, {{4851, {x -> 49}}}}}} 

那是一個開始,但它是壞的,因爲不知何故,我需要考慮到優先級更好,我需要完成的量每個管道。不知何故,我猜想金額也需要考慮到優先級。