简体   繁体   English

Microsoft Solver Foundation位置分散目标

[英]Microsoft Solver Foundation Location Dispersion Goal

I am trying to use the microsoft solver foundation so I could be able to select the 3 most dispersed locations out of a collection of locations. 我正在尝试使用微软解算器基础,这样我就可以从一组位置中选择3个最分散的位置。 I have added two goals to my model, one that ensures 3 locations are picked and another ensuring they are the 3 most dispersed locations. 我为我的模型添加了两个目标,一个确保选择3个位置,另一个确保它们是3个最分散的位置。

static void Main(string[] args)
    {
        Location candidate1 = new Location(0, 43.432, -79.432);
        Location candidate2 = new Location(1, 43.0, -79.0);
        Location candidate3 = new Location(2, 23.0, 29.0);
        Location candidate4 = new Location(3, 43.0, -79.0);
        Location candidate5 = new Location(4, 43.0, -79.0);
        Location[] candidates = {candidate1, candidate2, candidate3, candidate4, candidate5};
        SolverContext solver = new SolverContext();
        Model model = solver.CreateModel();
        model.Name = "LocationModel";
        Set items = new Set(Domain.Any, "candidates");
        Decision take = new Decision(Domain.Boolean, "candidate", items);
        model.AddDecision(take);
        Parameter locations = new Parameter(Domain.RealNonnegative, "locations", items);
        locations.SetBinding(candidates, "ID", "ID");
        model.AddParameter(locations);


        var dist = from l1 in candidates from l2 in candidates select new { ID1 = l1.ID, ID2 = l2.ID, dist = Geography.GetDistance(l1.Latitude, l1.Longitude, l2.Latitude, l2.Longitude) };
        Parameter distance = new Parameter(Domain.RealNonnegative, "Location", items, items);
        distance.SetBinding(dist, "dist", "ID1", "ID2");
        model.AddParameter(distance);            
        Term goal = Model.Sum(Model.ForEach(items, i => Model.ForEach(items, j => take[i]*take[j]* distance[i, j])));

        model.AddConstraint("LocationsQuantityMax", Model.Sum(Model.ForEach(items, item => take[item])) == 3);
        model.AddGoal("Dispersion", GoalKind.Maximize, goal); 

        Directive directive = new HybridLocalSearchDirective();            
        Solution solution = solver.Solve(directive);
        List<Location> locations1 = new List<Location>();
        if (solution.Decisions.Any())
        {
            var selections = solution.Decisions.First().GetValues()
                .Where(d => (bool) d[0])
                .Select(d => Convert.ToInt32(d[1]));

            locations1.AddRange(
                from c in candidates
                join s in selections on c.ID equals s
                select c);
        }

        foreach (Location location in locations1)
        {
            Console.WriteLine("ID: {0}, Latitude: {1}, Longitude: {2}", location.ID, location.Latitude, location.Longitude);
        } 

Additionally my Location class looks as follows: 另外,我的Location类看起来如下:

class Location
{
    public int ID { get; private set; }
    public double Latitude { get; private set; }
    public double Longitude { get; private set; }

    public Location(int LocationID, double latitude, double longitude)
    {
        this.ID = LocationID;
        this.Latitude = latitude;
        this.Longitude = longitude;
    }
} 

and my distance calculation is: 我的距离计算是:

    public static double ToRad(this double num)
    {
        return num * Math.PI / 180;
    }

    public static double GetDistance(double lat1, double lon1, double lat2, double lon2)
    {
        const int r = 6371; // Radius of earth in KM

        // Convert to Radians
        lat1 = lat1.ToRad();
        lon1 = lon1.ToRad();
        lat2 = lat2.ToRad();
        lon2 = lon2.ToRad();

        // Spherical Law of Cosines
        var resultCos =
            Math.Acos(
                Math.Sin(lat1) * Math.Sin(lat2) +
                Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(lon2 - lon1)
                ) * r;

        return resultCos;
    } 

Now my code has two problems and I dont know where they originate, 现在我的代码有两个问题,我不知道它们来自哪里,

Firstly, 首先,

my code as it stands works for most permutations of 5 locations with three of them being identical longitude latitude (ie in this; example candidate2, candidate4 and candidate5) but for certain permutations of candidates it will not return the most dispersed 3 (ie for the same problem instance just change the order of the candidates declaration). 我的代码适用于5个位置的大多数排列,其中三个是相同的经度纬度(即在此;例如候选2,候选4和候选5),但对于候选的某些排列,它将不会返回最分散的3(即同样的问题实例只是改变候选人声明的顺序)。 I cant fathom why. 我无法理解为什么。

Secondly, 其次,

If you comment out the constraint to select at least 3 locations, instead of selecting all of the locations like expected it selects none. 如果您注释掉约束以选择至少3个位置,而不是选择预期的所有位置,则选择无。

The fact that my goal works for most instances seems to indicate its correct, does anybody have an idea why it falters sometimes? 我的目标适用于大多数情况的事实似乎表明它是正确的,是否有人知道为什么它有时会动摇?

This is not homework and thanks a lot to whomever replies. 这不是家庭作业,非常感谢任何回复者。

I believe the issue is that you're specifying the HybridLocalSearchDirective . 我认为问题在于您指定了HybridLocalSearchDirective I removed that from your posted code and got the optimal answer: 我从你发布的代码中删除了它并获得了最佳答案:

ID: 0, Latitude: 43.432, Longitude: -79.432
ID: 1, Latitude: 43, Longitude: -79
ID: 2, Latitude: 23, Longitude: 29

Rearranging the terms or even adding new Locations still results in the optimal solution. 重新排列条款甚至添加新位置仍会产生最佳解决方案。

Additionally, I then removed the constraint and your code selected all five Location objects as the solution. 此外,我随后删除了约束,您的代码选择了所有五个Location对象作为解决方案。

I wish I could shed some light on why this works, but I'm just a weekend warrior when it comes to MSF. 我希望我能说清楚为什么会这样有效,但在无国界医生方面,我只是一个周末战士。 This is the most information I can find about the HybridLocalSearchDirective and how it arrives at a solution. 这是我能找到的关于HybridLocalSearchDirective以及它如何到达解决方案的最多信息 Importantly, the first limitation noted is: 重要的是,第一个限制是:

It does not guarantee optimal results. 它不能保证最佳结果。

This could be the answer to your first question (why it does not return the maximally dispersed locations). 这可能是您第一个问题的答案(为什么它不会返回最大分散的位置)。

As to your second question (why does removing the constraint not result in more selected Locations), I can't say for sure. 至于你的第二个问题(为什么删除约束不会产生更多选定的位置),我不能肯定地说。 Your problem specification could possibly be a degenerate case for that directive, though I can't figure out why. 您的问题规范可能是该指令的退化情况,但我无法弄清楚原因。

Not the best answer, but I hope it helps! 不是最好的答案,但我希望它有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM