function variants_lp_write ( filename, label, A, b, p_num, d )

%*****************************************************************************80
%
%% variants_lp_write() writes an LP file for a chromino splitting problem.
%
%  Discussion:
%
%    An LP file is a file written in a standard format for problems in
%    linear programming and related fields.
%
%    This function creates an LP file defining a problem in which a region R
%    is to be tiled, using F free polyominoes.  Each polyomino Pi is to be 
%    used ni times and d = [n1 n2 ... nF]. 
%
%    The LP file defines a problem that generalizes the checkerboard parity 
%    equation in which two colours are used on the region to be tiles. 
%    For this new formulation, C colours are used.  Colours are associated with
%    the region R and the F polyominoes.  Thus we have C*F pariominoes. 
%
%    The solution of the LP problem yields the chromino tiling subproblems. 
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    13 February 2023
%
%  Author:
%
%    John Burkardt, Marcus Garvie
%
%  Input:
%
%    string filename: the output filename, such as 'test.lp'.
%
%    string label: the problem title, such as '\ test'.
%    The label should begin with a backslash.
%
%    integer A(m,n): the coefficients of the constraints.
%
%    integer b(m): the right hand sides of the constraints.
%
%    integer p_num: the number of free polyominoes.
%
%    integer d(1,f): the numbers of copies of the polyominoes used.
%
%  Local:
%
%    integer C: the number of colours used (excluding holes, which are
%    coloured white). Here C must satisfy 2 <= C <= 6.
% 

%
%  Get some dimensions.
%
  [ m, n ] = size ( A );
%
%  Determine the number of colours, C.
%
  C = round ( n / p_num );   
%
%  Open the file.
%
  output = fopen ( filename, 'wt' );

  if ( output < 0 ) 
    fprintf ( 1, '\n' );
    fprintf ( 1, 'polyomino_lp_write(): Error!\n' );
    fprintf ( 1, '  Could not open the output file.\n' );
    error ( 'polyomino_lp_write(): Error!' );
  end

  fprintf ( output, '%s \n', label );
  fprintf ( output, '\n' );
%
%  GUROBI can't handle the "obj: 0" value for the Maximize field,
%  and both GUROBI and CPLEX are OK with a blank value instead.
%
  fprintf ( output, 'Maximize\n' );
  fprintf ( output, '  obj:  \n' );

  fprintf ( output, 'Subject to\n' );
  line_length = 0;

  for i = 1 : m

    first = true;

    for j = 1 : n

      if ( A(i,j) ~= 0 )

        if ( A(i,j) < 0 )
          byte_num = fprintf ( output, ' -' );
          line_length = line_length + byte_num;
        elseif ( ~ first )
          byte_num = fprintf ( output, ' +' );
          line_length = line_length + byte_num;
        end

        if ( abs ( A(i,j) ) == 1 )
          byte_num = fprintf ( output, ' x%d', j );
          line_length = line_length + byte_num;
        else
          byte_num = fprintf ( output, ' %d x%d', abs ( A(i,j) ), j );
          line_length = line_length + byte_num;
        end

        if ( 70 <= line_length )
          fprintf ( output, '\n' );
          fprintf ( output, '  ' );
          line_length = 2;
        end

        first = false;

      end
    end
    numbytes = fprintf ( output, ' = %d\n', b(i) );
    line_length = 0;
  end
  
  fprintf ( output, 'Bounds\n' );
  line_length = 0;
  
  k = 0;
  
  for i = 1 : p_num
    ni = d(i);
    for j = 1 : C
      k = k + 1;
      fprintf ( output, ' 0 <= x%d <= %d\n', k, ni );  
    end
  end
          
  fprintf ( output, 'General\n' );
  line_length = 0;

  byte_num = fprintf ( output, ' ' );
  line_length = line_length + byte_num;

  for j = 1 : n
    byte_num = fprintf ( output, ' x%d', j );
    line_length = line_length + byte_num;
    if ( 73 <= line_length & j < n )
      fprintf ( output, '\n' );
      fprintf ( output, '  ' );
      line_length = 2;
    end
  end

  fprintf ( output, '\n' );

  fprintf ( output, 'End\n' );
%
%  Close the file.
%
  fclose ( output );

  return
end
