2017-08-23 27 views
0

我有以下問題:分手了長度

我有一個長度,並希望其分割成幾部分和不同的規則,第一部分,任何中間部分最後一部分必須履行。

如果我有一個基於最小長度,最大長度和必須驗證所有部件的快照的規則,我已經爲該問題提供了一個工作解決方案,但現在問題變得更加複雜,我需要調整它。這個問題是否存在一個算法?有人有想法嗎?

例如:

  • 規則第一部分:從500長度 - 1000被允許在10
  • 規則中間部分的以下步驟:從300長度 - 600被允許在10
  • 規則的步驟最後一部分:從100長度 - 200被允許在10

思想的步驟: 拆分多達長度到您檢查規則1的第一部分和規則2進行所有以下(你份不知道你是否已經到達最後一部分)。如果你知道你到達最後一部分,那麼檢查最後一部分的規則3。問題:第3條規則可能會發生,最後一部分是無效的,這可能會在新的中間部分結束。這利茲進一步的問題...

讓我們嘗試的例子,試圖分裂的1500長度:

1)我們通過使用第一規則第1部分和第二把它分成1000和500排除所有其他

2)我們在最後一部分應用規則3 =>我們得到了1000和200現在的300

3),現在休息嗎?從這裏開始什麼是好邏輯?我知道在這種情況下,我會將第1部分拆分爲700和300,並且將第300部分添加到第2部分,結果將是700 - 600 - 200,但是如何將其包含到可以使用任意規則的邏輯中?

任何想法?

目標

分裂的部分應儘可能在末開始,只有部分大要小一些

附加的可選條件

我不知道,如果這是100%可以解決的。我可以添加以下條件:

  • 所有規則使用相同扣,這有助於尋找最佳的最後兩個部分,每個部分規則的
  • 分鐘長度> =比卡

編輯

  • 捕捉手段零件必須處於捕捉步驟。 500至1000爲10的卡扣裝置500,510,520,530 ... 980,990,1000是有效的數字
  • 我的優選的解決方案應當爲最大長度和爲較少的部件儘可能被優化
+0

當你說有一個快照值,這意味着你不能在任意點拆分,但只能在預定義的點,對嗎? – jdehesa

+0

正確,添加了一些編輯以使定義更加嚴格。我想要一個適用於任何規則的解決方案,但我也會滿足於有一些限制的解決方案 – prom85

+0

在最小和最大長度之上是否還有其他類型的規則?所有中間部分的長度必須相同,也可以是middle.min和middle max之間的任意長度。我們應該優化最大長度還是最小長度?你能解釋一下'快照'究竟意味着什麼嗎? – Selindek

回答

0

1)爲第一個分配500。

2)爲第一中間分配300。

3)保持分配300,直到還剩下什麼,如果小於300

4.1)如果是200和300之間剩下,增加第100,這樣剩下將是100和200之間,然後將其設置爲最後一個。 4.2)如果剩下的是100到200之間,則將其分配給最後一個。 4.3)如果剩下的是0到100之間,則銷燬最後一箇中間體,並將其長度分爲第一個和最後一個。第一個獲得200多個,剩下的最後一個將是100個,意味着100到200之間,然後將其設置爲最後一個。

評論如果不明確

+0

我添加了一些額外的信息。目標是始終擁有儘可能大的部件,並且最終只有較小的部件 – prom85

0

這是JAVA的解決方案。我假設所有參數都是快照的倍數。 (如果不是這種情況,那麼在調用此方法之前將它們四捨五入)。它只是將結果打印到控制檯中。你也可以把它收集到一個數組中並返回。

private void doSplit(int length, int fmin, int fmax, int mmin, int mmax, int lmin, int lmax) { 
    int k = Math.max(0, (length - fmax - lmax)/mmax); 
    int kmax = (length - fmin - lmin)/mmin; 
    boolean found = false; 
    while (k <= kmax) { 
     if (length <= fmax + lmax + k * mmax && length >= fmin + lmin + k * mmin) { 
      found = true; 
      break; 
     } 
     k++; 
    } 
    if (!found) { 
     throw new IllegalArgumentException("No solution"); 
    } 
    // k is the number of middle parts 
    System.out.println("Number of parts: first + last + middle x " + k); 
    int leftover = length - fmin - lmin - k * mmin; 
    int add = Math.min(fmax - fmin, leftover); 
    leftover -= add; 
    System.out.println("First: " + (fmin + add)); 
    for (int i = 0; i < k; i++) { 
     add = Math.min(mmax - mmin, leftover); 
     leftover -= add; 
     System.out.println("Middle: " + (mmin + add)); 
    } 
    add = Math.min(lmax - lmin, leftover); 
    leftover -= add; 
    System.out.println("Last: " + (lmin + add)); 

}