- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
西安科技大学
程序设计实训报告
班级: ^^^^^^^^^^^
学号: ^^^^^^^^^^
姓名: ^^^^^^
2012 年 6 月 20 日
题目 指派问题的匈牙利法
一、算法思想
本程序根据课本上匈牙利算法思想做了如下操作:首先定义结构体 ASS 用于存储
该矩阵中每个元素, 并且定义结构体 TrueOrForse 用于判断矩阵中每个元素是否被标记。
并且定义了相应函数(例如:输出函数)来完成相关操作。
(注释:具体操作见第二步, 算法流程与步骤。 具体结构体与相关函数祥见源程序首部
定义)
二、算法流程与步骤
初始化:
本程序首先根据用户输入转换为其相应的方阵(即行数等于列数) 。若人的数量乘
以每个人最多工作的任务数量小于或等于任务数量,同时补 n 行 0 ;否则补 n 列 0。(n
为任务数量减去人的数量乘以每个人最多工作的任务数量的绝对值) 。输出该方阵,方
便用户检查输入是否正确。
标记:
然后根据用户输入判断是按行减去每行最小值, 还是减去每列最小值 (注释:若人
的数量乘以每个人最多工作的任务数量小于或等于任务数量, 则减去每行最小值, 否则
则减去每列最小值) 。然后从中选择其中含 0 最多的行或列依次进行标记,若所标记的
直线数量小于矩阵行数(或列数) ,则撤销所有标记,选择其中含 0 最少的行(或列)
减去其中除 0 以外的最小值, 并同时将该行出现负数所在列 (或行)每个元素加上该负
数的相反数。重复以上操作,直到所标记的直线数等于矩阵行数(或列数) 。
转换为 0-1 指派矩阵:
从行与列中选择含零最少的行(或列) ,将该行(或列)中的零元素先转换为矩阵
中不可能出现的一个很大的数, 将零出现的行与列进行标记, 然后从列(或行) 中选择
零最少的,并将其中未被标记零元素转化为很大的数,依此类推;直到标记完所有数,
最后将很大的数转换为 1,其余均转化为 0 。即得 0-1 指派矩阵。
三、算法源程序
#include stdio.h
#include malloc.h
#include stdlib.h
#include conio.h
#include string.h
#define MAXCOUNT 50 // 最大的人数和任务数量
#define TRUE 1
#define FALSE 0
#define INDEF 10000 // 指派中不可能出现的数
struct TrueOrForse
{
int marker;
}; // 用于记录某元素是否被标记
typedef struct ASS
{
int assign[MAXCOUNT][MAXCOUNT];
struct TrueOrForse sign[MAXCOUNT][MAXCOUNT];
}Assign; //记录指派中各元素,及其是否被标记
void Print(int a[][MAXCOUNT],int Row,int Col); // 输出 0-1 指派构成的矩
阵
void reduceRow(Assign*L,int Row,int Col);
文档评论(0)