के लिए सहायता की आवश्यकता है मुझे एक एल्गोरिदम लागू करना है जो किसी भी किनारे की लंबाई और एक विशिष्ट राशि के लिए सभी possibile जादू वर्ग बनाता है। एन = 3 के लिए एल्गोरिदम अपेक्षित के रूप में काम कर रहा है। लेकिन जब मैं कुछ समय के बाद n = 4 के लिए सभी जादू वर्ग उत्पन्न करता हूं तो मैं स्मृति से बाहर निकलता हूं। कार्य समस्या में इस समस्या का पहले ही उल्लेख किया गया था। मैंने पहले ही कोड को अनुकूलित करने का प्रयास किया है, लेकिन यह अभी भी काम नहीं कर रहा है जैसा कि इसे करना चाहिए। तो मुझे उम्मीद है कि कोई मुझे कुछ सलाह दे सकता है।एरलांग में जादू वर्गों को उत्पन्न करते समय बहुत अधिक स्मृति खपत - विश्वविद्यालय के लिए अनुकूलन
मेरा मूल विचार यह है: सबसे पहले मैं सभी संभावित पंक्तियां उत्पन्न करता हूं जिन्हें मैं दिए गए नंबरों के साथ उपयोग कर सकता हूं और फिर मैं इन तरीकों को गठबंधन करने की कोशिश कर रहा हूं कि एक जादू वर्ग के प्रतिबंध पूर्ण हो गए हैं। यह बैकट्रैकिंग के माध्यम से होता है। मुझे लगता है कि समस्या makeRows
है जो सभी पंक्तियों को संग्रहीत करने के दौरान बहुत अधिक स्मृति का उपभोग करती है।
यदि आपको कोड के कुछ और स्पष्टीकरण की आवश्यकता है तो मैं दे सकता हूं!
magicSquare(N, Value) ->
Squares = buildSquare(N, makeRows(N, N*N, Value, N)),
io:fwrite("Squares ready"), io:fwrite("~n"),
Result = lists:filter(fun(X) -> testsquare(X, N, Value) end, Squares),
io:write(length(Result)),
Result.
buildSquare(0, _) -> [[]];
buildSquare(Rows, AvailableRows) ->
[ [X|L] || L <- buildSquare(Rows-1, AvailableRows), X <- AvailableRows, onlyUniqueNumbers(lists:flatten([X|L]))].
onlyUniqueNumbers(List) -> erlang:length(List) == sets:size(sets:from_list(List)).
%produces all possible rows with a dimension of Fields and the Numbers from 1 to Numbers and the right sum for each row
makeRows(0,_,_,_) -> [[]];
makeRows(Fields, Numbers, Value, TargetLength) ->
[ [X|L] || X <- makeRows(Fields-1, Numbers, Value, TargetLength), L <- lists:seq(1,Numbers), checkRow([X|L], TargetLength, Value)].
checkRow(Row, Length, Value) when length(Row) < Length -> true;
checkRow(Row, Length, Value) ->
Sum = lists:sum(Row),
if Sum == Value -> true;
true -> false
end.
testsquare(Square, N, Value) -> checkAllDiagonal(Square, Value) andalso checkAllHorizontal(Square, Value) andalso checkAllVertical(Square, N, Value).
checkAllHorizontal([H|T], Value) ->
case checkHorizontal(H, Value, 0) of
true -> checkHorizontal(lists:nth(1, T), Value, 0);
false -> false
end;
checkAllHorizontal([], Value) -> true.
checkHorizontal([H|T], Value, Summe) -> checkHorizontal(T, Value, Summe + H);
checkHorizontal([], Value, Summe) when Summe == Value -> true;
checkHorizontal([], Value, Summe) -> false.
checkAllVertical(Square, N, Value) -> checkAllVertical(Square, N, Value, 1).
checkAllVertical(Square, N, Value, Column) ->
if
Column > N -> true;
true ->
case checkVertical(Square, Value, 0, Column) of
true -> checkAllVertical(Square, N, Value, Column + 1);
false -> false
end
end.
checkVertical([], Value, Summe, Column) when Summe == Value -> true;
checkVertical([], Value, Summe, Column) -> false;
checkVertical([H|T], Value, Summe, Column) -> checkVertical(T, Value, Summe + lists:nth(Column, H), Column).
checkAllDiagonal(Square, Value) ->
case checkDiagonal(Square, Value, 0, 1,1) of
true -> case checkDiagonal(Square, Value, 0, length(lists:nth(1, Square)),-1) of
true -> true;
false -> false
end;
false -> false
end.
checkDiagonal([H|T], Value, Summe, Position, Richtung) -> checkDiagonal(T, Value, Summe + lists:nth(Position, H), Position + Richtung, Richtung);
checkDiagonal([], Value, Summe, Position, Richtung) when Summe == Value -> true;
checkDiagonal([], Value, Summe, Position, Richtung) -> false.
ठीक है मैंने गणना प्रक्रिया में पहले पंक्तियों और वर्गों के लिए चेक जोड़ने की कोशिश की है। संशोधित फ़ंक्शन यहां दिए गए हैं।
buildSquare(0, _, _, _) -> [[]];
buildSquare(Rows, AvailableRows, RowLength, Value) ->
[ [X|L] || L <- buildSquare(Rows-1, AvailableRows, RowLength, Value), X <- AvailableRows, validateSquare([X|L], RowLength, Value)].
checkOnlyUniqueNumbers(List) -> erlang:length(lists:flatten(List)) == sets:size(sets:from_list(lists:flatten(List))).
validateSquare(List, RowLength, Value) when length(List) == RowLength -> testsquare(List, RowLength, Value) andalso checkOnlyUniqueNumbers(List);
validateSquare(List, _,_) -> checkOnlyUniqueNumbers(List).
%produces all possible rows with a dimension of Fields and the Numbers from 1 to Numbers
makeRows(0,_,_,_) -> [[]];
makeRows(Fields, Numbers, Value, TargetLength) ->
[ [X|L] || L <- makeRows(Fields-1, Numbers, Value, TargetLength), X <- lists:seq(1,Numbers), checkRow([X|L], TargetLength, Value)].
%Checks if the sum of the row is Value when the row has the needed length Length
checkRow(Row, Length, _) when length(Row) < Length -> checkOnlyUniqueNumbers(Row);
checkRow(Row, _, Value) ->
Sum = lists:sum(Row),
Sum == Value andalso checkOnlyUniqueNumbers(Row).
हाँ बस मुझे लगता है कि कोड लड़के में नीचे स्क्रॉल करें। – soupdiver
क्या हम यहां कुछ सहमति जोड़ सकते हैं? Erlang निंजा, यहाँ समानांतर क्या किया जा सकता है? –
मैंने इसके बारे में भी सोचा लेकिन अब के लिए मैं खुश रहूंगा अगर एल्गोरिदम सामान्य रूप से काम करेगा (48 जीबी से कम RAM के साथ)। मुझे लगता है कि वर्गों के निर्माण की प्रक्रिया को समानांतर किया जा सकता है लेकिन मुझे पूरा यकीन नहीं है कि मैं डबल गणना – soupdiver