Скачиваний:
6
Добавлен:
26.05.2014
Размер:
13.12 Кб
Скачать
/*Distribution v1.0 - solves assignment problems with Hungarian algoritm
Copyright (C) 2006 Lord Ruslan Nightmare

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Mail me at LordRuslanNightmare@gmail.com
*/

#include <stdio.h>

#define NONE ' '
#define MARK '.'
#define STRK '-'

void OutArrayToFile(int **c, int x, int y, FILE *fo)
{
  int i,j,k;
  //fprintf(fo,"\n");
  for (j = 0; j < y+2; j++) 
  {
    if (j == y) 
    {
      for (k = 0; k <= x; k++)
      {
        if (k == x) fprintf(fo,"+");
        else fprintf(fo,"---");
      }      
      fprintf(fo,"\n");
    }
    for (i = 0; i < x+2; i++) 
    {
      if (i == x)
      {
        if (j < y) fprintf(fo,"|");
        else fprintf(fo,"   ");
      }
      if ((i < x) || (j < y)) fprintf(fo,"%3d",c[i][j]);
    }
    fprintf(fo,"\n");
  }
  fprintf(fo,"\n");
}

void OutArrayToFile(char **c, int x, int y, FILE *fo)
{
  int i,j,k;
  //fprintf(fo,"\n");
  for (j = 0; j < y+2; j++) 
  {
    if (j == y) 
    {
      for (k = 0; k <= x; k++)
      {
        if (k == x) fprintf(fo,"+");
        else fprintf(fo,"---");
      }      
      fprintf(fo,"\n");
    }
    for (i = 0; i < x+2; i++) 
    {
      if (i == x)
      {
        if (j < y) fprintf(fo,"|");
        else fprintf(fo,"   ");
      }
      if ((i < x) || (j < y)) fprintf(fo,"  %c",c[i][j]);
    }
    fprintf(fo,"\n");
  }
  fprintf(fo,"\n");
}



void OutHybridArrayToFile(int **c, char **mark1, int x, int y, FILE *fo)
{
  int i,j,k;
  //fprintf(fo,"\n");
  for (j = 0; j < y+2; j++) 
  {
    if (j == y) 
    {
      for (k = 0; k <= x; k++)
      {
        if (k == x) fprintf(fo,"+");
        else fprintf(fo,"----");
      }      
      fprintf(fo,"\n");
    }
    for (i = 0; i < x+2; i++) 
    {
      if (i == x)
      {
        if (j < y) fprintf(fo,"|");
        else fprintf(fo,"    ");
      }
      if ((i < x) || (j < y)) fprintf(fo,"%3d%c",c[i][j],mark1[i][j]);
    }
    fprintf(fo,"\n");
    if (j < y) for (k = 0; k <= x; k++) if (k == x) fprintf(fo,"    |"); else fprintf(fo,"   ");
    fprintf(fo,"\n");
  }
  fprintf(fo,"\n");
}

int PnctRows(int **c,char **mark1,int x,int y)
{
  int i,j;
  int marked = 0;
  for (j = 0; j < y; j++)
  {
//    int foundstrikednulls = 0;
    if (mark1[x][j] == NONE)
    { 
      mark1[x][j] = MARK;
      for (i = 0; i < x; i++)
      {
//        if ((c[i][j] == 0) && (mark1[i][j] == STRK)) foundstrikednulls = 1;
        if ((c[i][j] == 0) && (mark1[i][j] == MARK) && (mark1[i][y] == NONE))
        {         
          mark1[x][j] = NONE;
          break;
        }
      }
      if ((mark1[x][j] == MARK) && !marked) marked = 1;
//      if (!foundstrikednulls) mark1[x][j] = NONE;
    }
  }
  for (i = 0; i < x; i++)
  {
    int foundstrikednulls = 0;
    if (mark1[i][y] == NONE) 
    {
      mark1[i][y] = MARK;
      for (j = 0; j < y; j++)
      {
        if ((c[i][j] == 0) && (mark1[i][j] == STRK))
        {
          foundstrikednulls = 1;
          if (mark1[x][j] == NONE)
          {
            mark1[i][y] = NONE;
            break;
          }
        }
      }
      if ((mark1[i][y] == MARK) && !marked && foundstrikednulls) marked = 1;
      if (!foundstrikednulls) mark1[i][y] = NONE;
    }
  }
  return marked;
}



int main( int argc , char *argv[ ])
{
  FILE *fi, *fo;
  int x,y;

  if (argc != 3)
  {
    printf("Distribution v1.0, copyright (c) 2006 Lord Ruslan Nightmare\n");
    printf("Distribution v1.0 comes with ABSOLUTELY NO WARRANTY; for details see license.txt\n");
    printf("This is free software, and you are welcome to redistribute it\n");
    printf("under certain conditions; for details see license.txt\n");
    printf("Usage : distribution.exe input.txt output.txt\n");
    printf("Input.txt should contain matrix width and height, and then matrix itself. Example:\n");
    printf("4 4\n1  4  6  3\n9  7  10 9\n4  5  11 7\n8  7  8  5\n");
    return 0;
  }

  fi = fopen(argv[1],"r");
  fo = fopen(argv[2],"w");

  if (fseek( fi, 0L, SEEK_SET ) != 0) return 1;

  if (fscanf(fi,"%d %d",&x,&y) == EOF) return 1;

  int **c = new int*[x+2];
  int **s = new int*[x+2];

  int i,j,k,l;

  for (i = 0; i < x+2; i++)
  {
    c[i] = new int[y+2];
    s[i] = new int[y+2];
    for (j = 0; j < y+2; j++) c[i][j] = 0;
    for (j = 0; j < y+2; j++) s[i][j] = 0;
  }

  for (j = 0; j < y; j++) 
  {
    for (i = 0; i < x; i++) 
    {
      fscanf(fi,"%d",&c[i][j]);
      s[i][j] = c[i][j];
    }
  }

  fclose(fi);

  fprintf(fo,"Distribution v1.0, copyright (c) 2006 Lord Ruslan Nightmare\n");
  fprintf(fo,"Distribution v1.0 comes with ABSOLUTELY NO WARRANTY; for details see license.txt\n");
  fprintf(fo,"This is free software, and you are welcome to redistribute it\n");
  fprintf(fo,"under certain conditions; for details see license.txt\n\n");


  fprintf(fo,"Beginning calculations...\n");

  for (i = 0; i < x; i++) c[i][y] = 1;
  for (j = 0; j < y; j++) c[x][j] = 1;

  fprintf(fo,"Base matrix\n");
  OutArrayToFile(c,x,y,fo);

  for (j = 0; j < y; j++)
  {
    int m = c[0][j];
    for (i = 1; i < x; i++) if (c[i][j] < m) m = c[i][j];
    c[x+1][j] = m;
    for (i = 0; i < x; i++) c[i][j] -= m;
  }

  fprintf(fo,"Base matrix with nullified rows\n");
  OutArrayToFile(c,x,y,fo);

  for (i = 0; i < x; i++)
  {
    int m = c[i][0];
    for (j = 1; j < y; j++) if (c[i][j] < m) m = c[i][j];
    c[i][y+1] = m;
    for (j = 0; j < y; j++) c[i][j] -= m;
  }

  fprintf(fo,"Base matrix with nullified columns\n");
  OutArrayToFile(c,x,y,fo);

  char **mark1 = new char*[x+2];

  for (i = 0; i < x+2; i++)
  {
    mark1[i] = new char[y+2];
  }

  int markednulls = 0;

  int m = 0;
  int didntfound = 1;
  int iterations = 0;

  while (markednulls != y)
  {

    for (i = 0; i < x+2; i++)
    {
      for (j = 0; j < y+2; j++) mark1[i][j] = NONE;
    }

    for (j = 0; j < y; j++)
    {
      for (i = 0; i < x; i++)
      {
        if (c[i][j] == 0)
        {
          if (mark1[i][j] == NONE)
          {
            mark1[i][j] = MARK;
            for (k = i + 1; k < x; k++)
            {
              if (c[k][j] == 0)
              {
                mark1[i][j] = NONE;
                break;
              }
            }
            if (mark1[i][j] == MARK) 
            {
              for (k = 0; k < y; k++) 
              {
                if ((c[i][k] == 0) && (mark1[i][k] == NONE)) 
                {
                  mark1[i][k] = STRK;
                  }
              }            
            }
          }
          break;
        }
      }
    }

    for (i = 0; i < x; i++)
    {
      for (j = 0; j < y; j++)
      {
        if (c[i][j] == 0)
        {
          if (mark1[i][j] == NONE)
          {
            mark1[i][j] = MARK;
            for (k = j + 1; k < y; k++)
            {
              if (c[i][k] == 0)
              {
                mark1[i][j] = NONE;
                break;
              }
            }
            if (mark1[i][j] == MARK) 
            {
              for (k = 0; k < x; k++) 
              {
                if ((c[k][j] == 0) && (mark1[k][j] == NONE)) 
                {
                  mark1[k][j] = STRK;
                }
              }            
            }
          }
          break;
        }
      }
    }

    fprintf(fo,"'No alternatives' matrix marks\n");
    OutArrayToFile(mark1,x,y,fo);
    fprintf(fo,"'No alternatives' matrix\n");
    OutHybridArrayToFile(c,mark1,x,y,fo);


    for (j = 0; j < y; j++)
    {
      for (i = 0; i < x; i++)
      {
        if ((c[i][j] == 0) && (mark1[i][j] == NONE))
        {
          mark1[i][j] = MARK;
          for (k = i + 1; k < x; k++) if ((c[k][j] == 0) && (mark1[k][j] == NONE))mark1[k][j] = STRK;
          for (k = 0; k < y; k++) if ((c[i][k] == 0) && (mark1[i][k] == NONE)) mark1[i][k] = STRK;
        }
      }
    }
  
    fprintf(fo,"Matrix marks\n");
    OutArrayToFile(mark1,x,y,fo);
    fprintf(fo,"Marked matrix contents\n");
    OutHybridArrayToFile(c,mark1,x,y,fo);

    for (j = 0; j < y; j++)
    {
      for (i = 0; i < x; i++)
      {
        if ((c[i][j] == 0) && (mark1[i][j] == MARK))
        {
          mark1[x][j] = MARK; 
          break;
        }
      }
    }  
  
    for (i = 0; i < x; i++)
    {
      for (j = 0; j < y; j++)
      {
        if ((c[i][j] == 0) && (mark1[i][j] == MARK))
        {
          mark1[i][y] = MARK; 
          break;
        }
      }
    }  

    fprintf(fo,"Marks of matrix with marked rows/colums\n");
    OutArrayToFile(mark1,x,y,fo); 
    fprintf(fo,"Matrix with marked rows/colums\n");
    OutHybridArrayToFile(c,mark1,x,y,fo);
  
    for (i = 0; i < x; i++)
    {    
      if (mark1[i][y] == NONE)
        for (j = 0; j < y; j++)
        {
          int found = 0;
          if ((c[i][j] == 0) && (mark1[i][j] == STRK) && !found)
          {
            for (k = 0; k < x; k++)
            {
              if ((c[k][j] == 0) && (mark1[k][j] == MARK))
              {
                for (l = 0; l < y; l++)
                {
                  if ((c[k][l] == 0) && (mark1[k][l] == STRK) && (mark1[x][l] == NONE))
                  {
                    found = 1;
                    mark1[k][l] = MARK;
                    break;
                  }
                }
                if (found) 
                {
                  mark1[k][j] = STRK;
                  break;
                }
              }
            }
            if (found)
            {
              mark1[i][j] = MARK;
            }
          }
        }
    }  
  
    markednulls = 0;
    for (j = 0; j < y; j++)
    {
      for (i = 0; i < x; i++)
      {
        if ((c[i][j] == 0) && (mark1[i][j] == MARK))
        {
          markednulls++;
          break;
        }
      }
    }
  
    fprintf(fo,"Paired matrix marks\n");
    OutArrayToFile(mark1,x,y,fo);
    fprintf(fo,"Paired matrix\n");
    OutHybridArrayToFile(c,mark1,x,y,fo);
  
    iterations++;

    fprintf(fo,"There's %d marked nulls\n",markednulls);
    if ((markednulls == y) || (iterations == 10))
    {
      if (iterations == 10) fprintf(fo,"Failed to calculate the solution in 10 cycles\n");
      else
      {
        fprintf(fo,"Success! Elements marked with '.' is the solution\n");
        OutHybridArrayToFile(s,mark1,x,y,fo);
      }
      fclose(fo);
  
      return 0;
    }

    fprintf(fo,"It's not enough, we should modify matrix\n\n");

    for (i = 0; i < x+2; i++)
    {
      for (j = 0; j < y+2; j++) mark1[x][j] = NONE;
      mark1[i][y] = NONE;
    }

    while (PnctRows(c,mark1,x,y) == 1);

    fprintf(fo,"Marks of matrix with pre-punctured rows/columns\n"); 
    OutArrayToFile(mark1,x,y,fo);
    fprintf(fo,"Matrix with pre-punctured rows/columns\n"); 
    OutHybridArrayToFile(c,mark1,x,y,fo);

    for (j = 0; j < y; j++)
    {
      if (mark1[x][j] == NONE) mark1[x][j] = STRK;
      for (i = 0; i < x; i++)
      {
        if (mark1[i][y] == MARK) mark1[i][y] = STRK;
      }
    }

    fprintf(fo,"Marks of matrix with punctured rows/columns\n"); 
    OutArrayToFile(mark1,x,y,fo);
    fprintf(fo,"Matrix with punctured rows/columns\n"); 
    OutHybridArrayToFile(c,mark1,x,y,fo);

    m = 0;
    didntfound = 1;

    for (j = 0; j < y; j++)
    {
      for (i = 1; i < x; i++) 
      {
        if ((mark1[x][j] != STRK) && (mark1[i][y] != STRK))
        {
          if (didntfound)
          {
            m = c[i][j];
            didntfound = 0;
          }
          if (c[i][j] < m) m = c[i][j];
        }
      }
    }
    fprintf(fo,"Before modification\n"); 
    OutArrayToFile(c,x,y,fo);

    fprintf(fo,"Min unpunctured submatrix element = %d\n\n",m);
    
    for (j = 0; j < y; j++)
    {
      for (i = 0; i < x; i++) 
      {
        if (mark1[x][j] != STRK)
        {
          c[i][j] -= m;
        }
        if (mark1[i][y] == STRK)
        {
          c[i][j] += m;
        }
      }
    }

    fprintf(fo,"Modified matrix\n"); 
    OutArrayToFile(c,x,y,fo);

  } //while

  delete []c;
  delete []s;
  delete []mark1;
}
Соседние файлы в папке Программа для решения задачи о назначении (с сырцами)
  • #
    26.05.2014883 б6Distribution.sln
  • #
    26.05.201410.75 Кб6Distribution.suo
  • #
    26.05.20144 Кб6Distribution.vcproj
  • #
    26.05.201451 б6input.txt
  • #
    26.05.201418.33 Кб8license.txt
  • #
    26.05.201413.12 Кб6main.cpp