簡體   English   中英

Microsoft Solver Foundation位置分散目標

[英]Microsoft Solver Foundation Location Dispersion Goal

我正在嘗試使用微軟解算器基礎,這樣我就可以從一組位置中選擇3個最分散的位置。 我為我的模型添加了兩個目標,一個確保選擇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);
        } 

另外,我的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;
    }
} 

我的距離計算是:

    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;
    } 

現在我的代碼有兩個問題,我不知道它們來自哪里,

首先,

我的代碼適用於5個位置的大多數排列,其中三個是相同的經度緯度(即在此;例如候選2,候選4和候選5),但對於候選的某些排列,它將不會返回最分散的3(即同樣的問題實例只是改變候選人聲明的順序)。 我無法理解為什么。

其次,

如果您注釋掉約束以選擇至少3個位置,而不是選擇預期的所有位置,則選擇無。

我的目標適用於大多數情況的事實似乎表明它是正確的,是否有人知道為什么它有時會動搖?

這不是家庭作業,非常感謝任何回復者。

我認為問題在於您指定了HybridLocalSearchDirective 我從你發布的代碼中刪除了它並獲得了最佳答案:

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

重新排列條款甚至添加新位置仍會產生最佳解決方案。

此外,我隨后刪除了約束,您的代碼選擇了所有五個Location對象作為解決方案。

我希望我能說清楚為什么會這樣有效,但在無國界醫生方面,我只是一個周末戰士。 這是我能找到的關於HybridLocalSearchDirective以及它如何到達解決方案的最多信息 重要的是,第一個限制是:

它不能保證最佳結果。

這可能是您第一個問題的答案(為什么它不會返回最大分散的位置)。

至於你的第二個問題(為什么刪除約束不會產生更多選定的位置),我不能肯定地說。 您的問題規范可能是該指令的退化情況,但我無法弄清楚原因。

不是最好的答案,但我希望它有所幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM