匈牙利语方法-3种选择方式

问题描述

我对匈牙利的分配问题有疑问。

在我从匈牙利方法中发现的示例中,您拥有1到n个首选项。

因此,目前,我们在学校的任务是创建一个课程,您可以在该课程中上学(1至n个学生)。学生正好带一件礼物上课。所以(1表示学生人数)

此后,每个学生都恰好有3个选择(可以选择一份礼物,例如礼物1,礼物5,礼物9),并且我们的程序可以输出全班最佳作业。

但是正如前面提到的,我们发现有关匈牙利方法的示例具有1到n个偏好。我们正好需要三个。 我们将如何解决这一特定任务?

匈牙利方法仍然是解决此任务的最佳方法,还是我们应该看看另一种算法?

解决方法

我刚刚看到您的最后一个问题没有答案就被关闭了。

我已经实现了一种实用的方法来解决C#中的此问题,假设希望是在以下格式的csv文件中给出的:

2,10,6
2,7,3
4,1
...

列的数量(即首选项的数量)与我的实现无关紧要。

显然,性能仍有提升的空间,但是为了答案,我选择使其更具可读性。

以下是以下代码中使用的类:

public class Student
{
    public int StudentNumber { get; set; }
    public List<WishVote> WishVotes { get; set; }
}

public class WishVote
{
    public int WishNumber { get; set; }
    public int Order { get; set; }
    public string Id { get; set; }
}
public class WishVoteResult
{
    public int WishNumber { get; set; }
    // wish order
    // vote count for that order
    // wish number
    public List<Tuple<int,int,int>> Assignments { get; set; }
    public int TotalVoteCount { get; set; }
}

这是您可以在Main中运行的代码,以按降序输出希望数和投票总数:

var lines = File.ReadAllLines("wishes.csv").ToList();
int studentNumber = lines.Count;

var students = new List<Student>();

int currentLine = 0;
lines.ForEach(l =>
{
    currentLine++;

    var wishVotes = new List<WishVote>();
    int wishOrder = 0;
    l.Split(',').ToList().ForEach(w =>
    {
        wishOrder++;
        wishVotes.Add(new WishVote
        {
            Id = Guid.NewGuid().ToString(),Order = wishOrder,WishNumber = Convert.ToInt32(w)
        });

    });

    students.Add(new Student
    {
        StudentNumber = currentLine,WishVotes = wishVotes
    });

});

var allWishVotes = students.SelectMany(s => s.WishVotes).ToList();
List<int> uniqueWishes = allWishVotes.Select(w => w.WishNumber).Distinct().ToList();

var wishVoteResults = new List<WishVoteResult>();

// assuming every row in the file has the same number of columns
int orderCount = students.First().WishVotes.Max(w => w.Order);

uniqueWishes.ForEach(uw =>
{
    var wishVoteResult = new WishVoteResult
    {
        WishNumber = uw,TotalVoteCount = allWishVotes.Where(w => w.WishNumber == uw).Count(),Assignments = new List<Tuple<int,int>>()
    };

    for(int i = 1; i <= orderCount; i++)
    {
        wishVoteResult.Assignments.Add(new Tuple<int,int>(i,allWishVotes.Where(w => w.Order == i && w.WishNumber == uw).Count(),uw));
    }

    wishVoteResults.Add(wishVoteResult);
});

var assignments = wishVoteResults.SelectMany(w => w.Assignments).OrderByDescending(a => a.Item2).ThenBy(a => a.Item1).ToList();

Console.WriteLine("Wish {wishNumber}: {voteCount} {wishOrder}");
foreach (var assignment in assignments)
{
    Console.WriteLine($"Wish number {assignment.Item3}: {assignment.Item2} {assignment.Item1}");
}

Console.WriteLine("Finished.");

有效地,我们正在做的是创建所有可能的分配,然后进行相应的排序。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...