Я изучаю Фонд Solver прямо сейчас. Я фактически подключаю lpsolve для своего проекта, но я думаю, что моя проблема - общая проблема того, как лучше всего представлять мои ограничения.Представить географическое распределение в качестве ограничения в линейной задаче?
У меня есть, что я думаю, довольно типичный рюкзак или проблема упаковки. У меня есть коллекция мест, и у каждого есть «оценка». Я хочу выбрать минимальное количество мест для достижения целевой оценки.
(На практике это немного сложнее, чем это - каждое местоположение имеет несколько разных свойств, и я часто буду нацелен на несколько свойств).
Пока все хорошо. Однако у меня есть дополнительное ограничение - я хочу максимизировать географическое рассеивание выбранных мной местоположений. Как я могу представить это ограничение?
Вот простой пример того, что я прямо сейчас:
static void Main(string[] args)
{
var locations = new List<LocationWithScore>()
{
new LocationWithScore() { LocationID = 0, Latitude = 43.644274M, Longitude = -79.478703M, Score = 20 },
new LocationWithScore() { LocationID = 1, Latitude = 43.644709M, Longitude = -79.476814M, Score = 20 },
new LocationWithScore() { LocationID = 2, Latitude = 43.643063M, Longitude = -79.477458M, Score = 20 },
new LocationWithScore() { LocationID = 3, Latitude = 43.650516M, Longitude = -79.469562M, Score = 20 },
new LocationWithScore() { LocationID = 4, Latitude = 43.642659M, Longitude = -79.463124M, Score = 20 }
};
SolverContext sContext = SolverContext.GetContext();
sContext.ClearModel();
Model model = sContext.CreateModel();
model.Name = "LocationWithScore";
Set items = new Set(Domain.Any, "candidates");
Decision take = new Decision(Domain.Boolean, "candidate", items);
model.AddDecision(take);
Parameter scoreParam = new Parameter(Domain.RealNonnegative, "score", items);
scoreParam.SetBinding(locations, "Score", "LocationID");
model.AddParameters(scoreParam);
model.AddConstraint("scoreConstraint", Model.Sum(Model.ForEach(items, item => scoreParam[item] * take[item])) >= 60);
model.AddGoal("locationGoal", GoalKind.Minimize, Model.Sum(Model.ForEach(items, item => take[item])));
var solution = sContext.Solve(new LpSolveDirective());
var report = solution.GetReport();
Console.WriteLine(report.ToString());
Console.WriteLine("Done");
Console.ReadKey();
}
internal class LocationWithScore
{
public int LocationID { get; set; }
public decimal Latitude { get; set; }
public decimal Longitude { get; set; }
public double Score { get; set; }
}
Это будет просто выбрать первые три места, что дает мне моя цель 60, но эти три локации кластерные очень близко друг к другу. Я бы предпочел, чтобы он выбрал один из первых трех (ID 0 - 2) и два последних (ID 3 и 4), которые распространяются дальше.
Может кто-нибудь предложить некоторые рекомендации здесь? Спасибо заранее.
Я думал, что вы реализуете решение динамического программирования рюкзака с добавлением ограничения максимизации * d *, дисперсии единиц для предметов в вашем рюкзаке. – user845279
Спасибо, да. Любой ключ к тому, как лучше всего представить это как ограничение в Solver Foundation? – TheNextman
:) Я знаю, о чем вы думаете, * thx Captain Obvious *. Во всяком случае, попытались ли вы добавить дополнительную цель максимизации дисперсии? Вероятно, вам придется написать функцию, возможно, дисперсию, чтобы рассчитать дисперсию по заданным параметрам долготы и широты. – user845279