/* Maximum number of occurrences in Picat. https://stackoverflow.com/questions/62759396/count-most-frequent-element-in-an-array-in-minizinc Count most frequent element in an array in Minizinc """ It's a very simple thing that I want to do in Minizinc. I have an array of integer values, and I want to know the number of times that the most common value in it occurs. I can't figure out how to do that. I hope someone can help. """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go ?=> A = [15, 14, 39, 23, 14, 14, 8], N = A.len, max_number_of_occurrences(A, GCC,Z,MaxVal), println(a=A), println(gcc=GCC), println(z=Z), println(maxVal=MaxVal), nl, fail, nl. go => true. % Let A be free. go2 ?=> N = 10, A = new_list(N), A :: 0..12, max_number_of_occurrences(A, GCC,Z,MaxVal), println(a=A), println(gcc=GCC), println(z=Z), println(maxVal=MaxVal), nl, fail, nl. go2 => true. max_number_of_occurrences(A, GCC,Z,MaxVal) => N = A.len, % upper value of a Upb = fd_max_array(A), % Number of occurrences in A % Note: This is 0-based GCC = new_list(Upb+1), GCC :: 0..N, global_cardinality2(A, GCC), % max number of occurrenes Z #= max(GCC), % Z #> 3, % The value of the max number of occurrences argmax(MaxVal1,GCC), MaxVal #= MaxVal1-1, % Adjust for 0-based GCC Vars = A ++ GCC ++ [Z,MaxVal], solve($[ff,split],Vars). fd_max_array(X) = max([fd_max(V) : V in X]). % p is the position(s) of the maximum element(s) argmax(P, X) => foreach(I in 1..X.len) element(P,X,XP), XP #>= X[I] end. % % global_cardinality(A, Gcc) % % This version is bidirectional but limited: % % Both A and Gcc are (plain) lists. % global_cardinality2(A, Gcc) => Len = length(A), Max = length(Gcc), Gcc :: 0..Len-1, foreach(I in 0..Max-1) count(I,A,#=,Gcc[I+1]) end.