Solution

1 - Queen, 2 - Bishop, 3 - Knight, 4 - Rook

    3    2    2    2    3    4    1    2
    3    3    4    3    1    3    0    2
    3    0    1    4    3    0    3    2
    1    0    0    3    0    3    4    2
    2    4    3    0    3    1    3    0
    2    3    0    3    4    3    0    1
    2    1    3    0    3    0    3    4
    4    3    0    1    2    2    2    2


Xpress-Mosel Model
model 'crowd'

!  Description  : The crowded board
!  Source       : Dudeney, H.E., (1917), Amusements in Mathematics, Thomas Nelson and Sons.
!  Date written : Xpress-MP May 2000, Mosel 19/4/03
!  Written by   : M J Chlond

  uses 'mmxprs'

  parameters
    size = 8
    piece = 4    ! 1 - Queen, 2 - Bishop, 3 - Knight, 4 - Rook
  end-parameters

  declarations
    S = 1..size+4
    P = 1..piece+4
    R = 3..size+2  ! real part of board
    N: array(P) of real
    x: array(S,S,P) of mpvar
  end-declarations

  N:= [8,14,21,8]
   
  any:= sum(i in R,j in R,k in P) x(i,j,k)

  forall(k in P)
    nump(k):= sum(i in R,j in R) x(i,j,k) = N(k)
    
  forall(i in R,j in R)
    onep(i,j):= sum(k in P) x(i,j,k) <= 1

  ! No queens attack each other
  forall(i in R)
    qrow(i):= sum(j in R) x(i,j,1) <= 1
  forall(j in R)  
    qcol(j):= sum(i in R) x(i,j,1) <= 1     
  forall(i in 2..size+3)  
    qdia(i):= sum(k in 1..i) x(k,i-k+1,1) <= 1
  forall(j in 1..size+3)  
    qdib(j):= sum(k in j..size+4) x(k,size+4-k+j,1) <= 1  
  forall(j in 1..size+3)  
    qdic(j):= sum(k in 1..size-j+5) x(k,j+k-1,1) <= 1
  forall(i in 2..size+3)    
    qdid(i):= sum(k in i..size+4) x(k,k-i+1,1) <= 1

  ! No bishops attack each other
  forall(i in 2..size+3)
    bda(i):= sum(k in 1..i) x(k,i-k+1,2) <= 1
  forall(j in 1..size+3)
    bdb(j):= sum(k in j..size+4) x(k,size+4-k+j,2) <= 1
  forall(j in 1..size+3)
    dbc(j):= sum(k in 1..size-j+5) x(k,j+k-1,2) <= 1
  forall(i in 2..size+3)
    bdd(i):= sum(k in i..size+4) x(k,k-i+1,2) <= 1

  ! No rooks attack each other
  forall(i in R)
    rrow(i):= sum(j in 3..size+2) x(i,j,4) <= 1
  forall(j in R)
    rcol(j):= sum(i in 3..size+2) x(i,j,4) <= 1

  ! a(i,j,3) = 0 if square {i,i} attacked by knight 
  forall(i in R,j in R)
    knta(i,j):= x(i-2,j-1,3) + x(i-1,j-2,3) + x(i+1,j-2,3) + x(i+2,j-1,3) + 
                x(i+2,j+1,3) + x(i+1,j+2,3) + x(i-1,j+2,3) + x(i-2,i+1,3) + 99*x(i,j,3) <= 99

  ! Dummy squares not occupied 
  setzero:= sum(i in 1..size+4,j in 1..size+4,k in 1..4 | i < 3 or i > size+2 or 
                     j < 3 or j > size+2) x(i,j,k) =  0

  forall(i in R,j in R, k in P)
    x(i,j,k) is_binary
    
  minimise(any)
  
  forall(i in 1..size) do
    forall(j in 1..size)
      write(sum(k in P) k*getsol(x(i+2,j+2,k)),' ')
    writeln
  end-do

end-model