簡體   English   中英

如何避免 MiniZinc 中的 integer 溢出?

[英]How to avoid integer overflow in MiniZinc?

我正在嘗試使用 MiniZinc 為 Python 解決來自編碼游戲網站的代碼游戲。我所要做的就是在給定詞匯表(一組可能的單詞,轉換和連接, 應該恰好等於輸入的摩爾斯電碼)。 我已經能夠很快地找出解決方案,但問題是無論我使用什么求解器,我都會得到 integer 溢出。 我嘗試使用 OptiMathSAT,但無法成功應用。

在這里,您可以找到我的代碼(您不會找到可能組合的計數,但我認為它是直截了當的):

MORSE_CODE_DICT = { 'A':'12', 'B':'2111', 
                    'C':'2121', 'D':'211', 'E':'1', 
                    'F':'1121', 'G':'221', 'H':'1111', 
                    'I':'11', 'J':'1222', 'K':'212', 
                    'L':'1211', 'M':'22', 'N':'21', 
                    'O':'222', 'P':'1221', 'Q':'2212', 
                    'R':'121', 'S':'111', 'T':'2', 
                    'U':'112', 'V':'1112', 'W':'122', 
                    'X':'2112', 'Y':'2122', 'Z':'2211'}


# Input vocabulary converter to number
def converter(vocabulary):
    for i in range(len(vocabulary)):
        var = ""
        for j in vocabulary[i]:
            var = var+MORSE_CODE_DICT[j]
        vocabulary[i]=int(var)
    return vocabulary

# Create a MiniZinc model

gecode = Solver.lookup("or-tools")
model=Model()
model.add_string("""
include "globals.mzn";

int: n;
int: lmax;
array[1..n] of int: c;
int: morse;
array [1..lmax] of var 1..n: frase; 
var int: r;
array [1..n] of var int: len;
array [1..lmax] of var int: sa;

constraint forall(i in 1..n)(len[i]=string_length(mzn_version_to_string(c[i]))-4);
constraint sa[1]=c[frase[1]]; 
constraint forall(i in 2..lmax)(sa[i]=c[frase[i]]*pow(10,sum(j in 2..i)(len[frase[j-1]]))); 
constraint lmax>0 /\ lmax<100000;
constraint n>0 /\ n<100000;
constraint forall(i in len)(i>0 /\ i<20);
constraint r>=0 /\ r<pow(2,10);
constraint sum(sa) = morse;
""")

# Transform Model into a instance

inst = Instance(gecode, model)
inst["n"] = 6

vocabulary = ["HELL","HELLO","OWORLD","WORLD","TEST"]
vocabulary= np.array(converter(vocabulary))
vocabulary = np.append(vocabulary, 0)
print(vocabulary)
inst["c"] = vocabulary

morse = 11111121112112221222221211211211
inst["morse"] = morse

print(len(str(morse)));
inst["lmax"] = len(str(morse))

result = inst.solve()

你會如何解決這個問題? 你能給我一些關於問題的可能解決方案或不同方法的建議嗎? 我已經嘗試過使用字符串而不是整數,但 MiniZinc 對它們的支持不是很好。

提前謝謝大家。

大多數 FlatZinc 求解器不支持大整數並會產生溢出錯誤,例如在檢測大於 2**32 的整數運算時。 確切的限制取決於求解器。

model 中的一個問題是您有很多定義為var int的域,這些域會產生非常大的域供求解器使用。 如果您嘗試盡可能減少這些域,它可能會起作用。

在 MiniZinc model 中,我評論了一些約束並給所有var int一些(但可能是錯誤的)域,這些域給出了使用 OR-tools 求解器的解決方案:

include "globals.mzn";

int: n;
int: lmax;
array[1..n] of int: c;
int: morse;

array [1..lmax] of var 1..n: frase; 
var 0..pow(2,10): r; % hakank
array [1..n] of var 0..20: len; % hakank
array [1..lmax] of var 0..100000000: sa; % hakank

% constraint forall(i in 1..n)(len[i]=string_length(mzn_version_to_string(c[i]))-4);
constraint sa[1]=c[frase[1]]; 
% constraint forall(i in 2..lmax)(sa[i]=c[frase[i]]*pow(10,sum(j in 2..i)(len[frase[j-1]]))); 
constraint lmax>0 /\ lmax<100000;
% constraint n>0 /\ n<100000;
% constraint forall(i in len)(i>0 /\ i<20);
% constraint r>=0 /\ r<pow(2,10);
constraint sum(sa) = morse;

solve satisfy;

這是一個解決方案 - 如上所述 - 看起來不正確。 但是您現在可以使用約束和域。

Solution(frase=[5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 
         r=0, 
         len=[0, 0, 0, 0, 0, 0], 
         sa=[211112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47272535, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000, 100000000],    
         _checker='')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM