Добавил:
Fragga
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
/*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;
}