【问题标题】:Hungarian method - 3 choices assignment匈牙利方法 - 3 选择分配
【发布时间】:2020-10-06 11:48:02
【问题描述】:

我有一个关于分配问题的匈牙利方法的问题。

在我从匈牙利方法中找到的示例中,您有 1 到 n 个偏好。

因此,目前,我们在学校的任务是创建一个计划,其中您有一个学校班级(1 到 n 名学生)。学生们只拿了一份礼物给班级。所以(1 到学生的数量)

之后每个学生都有三个 CHOICES(选择一个礼物,例如礼物 1、礼物 5、礼物 9),我们的程序应该为班级输出最好的作业。

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

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

【问题讨论】:

  • 是的,现在已修复,谢谢 ;)

标签: variable-assignment relation


【解决方案1】:

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

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

2,10,6
2,7,3
4,7,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, int>>()
    };

    for(int i = 1; i <= orderCount; i++)
    {
        wishVoteResult.Assignments.Add(new Tuple<int, 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.");

实际上,我们所做的是创建所有可能的分配,然后进行相应的排序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-15
    • 2013-05-18
    • 2015-09-02
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多