這是我第一次與Solver Foundation合作,我不明白如何指定目標函數。我試圖用Solver解決的問題是基於目標函數在2D表面上找到最佳點。作爲輸入數據,我在這個表面上有3點,聲波需要從源(最佳點)到這三點之間的時間差。這個時間差異導致距離差異。使用Solver找到2D區域上的最佳點
這裏是我的代碼:
var solver = SolverContext.GetContext();
var model = solver.CreateModel();
decisionX = new Decision(Domain.Real, "X");
decisionY = new Decision(Domain.Real, "Y");
model.AddDecision(decisionX);
model.AddDecision(decisionY);
model.AddGoal("Goal", GoalKind.Minimize, GoalFunction());
var solution = solver.Solve();
Console.WriteLine("X " + decisionX.GetDouble());
Console.WriteLine("Y " + decisionY.GetDouble());
GoalFunction()的定義如下:
double GoalFunction() {
Location X = new Location(decisionX.ToDouble(), decisionY.ToDouble());
var rA = A.Location.Distance(X);
var rB = B.Location.Distance(X);
var rC = C.Location.Distance(X);
rA = (Distance)(rA - dsA);
rB = (Distance)(rB - dsA);
rC = (Distance)(rC - dsA);
return (rA * rA + rB * rB + rC * rC)/3;
}
上面的代碼拋出異常(decisionX.ToDouble()
),因爲決定不是在這一點上初始化。
有人可以幫我改寫嗎?
我已將我的GoalFunction改寫爲all-Model.methods-calls。
var solver = SolverContext.GetContext();
var model = solver.CreateModel();
decisionX = new Decision(Domain.Real, "X");
decisionY = new Decision(Domain.Real, "Y");
model.AddDecision(decisionX);
model.AddDecision(decisionY);
var rA = Model.Difference(
Model.Sqrt(
Model.Sum(
Model.Power(Model.Difference(decisionX, A.Location.X), 2),
Model.Power(Model.Difference(decisionY, A.Location.Y), 2)
)
),
dsA.Value
);
var rB = Model.Difference(
Model.Sqrt(
Model.Sum(
Model.Power(Model.Difference(decisionX, B.Location.X), 2),
Model.Power(Model.Difference(decisionY, B.Location.Y), 2)
)
),
dsB.Value
);
var rC = Model.Difference(
Model.Sqrt(
Model.Sum(
Model.Power(Model.Difference(decisionX, C.Location.X), 2),
Model.Power(Model.Difference(decisionY, C.Location.Y), 2)
)
),
dsC.Value
);
var miner = Model.Min(rA, rB, rC);
rA = Model.Difference(rA, miner);
rB = Model.Difference(rB, miner);
rC = Model.Difference(rC, miner);
var goal = Model.Sum(
Model.Power(rA, 2),
Model.Power(rB, 2),
Model.Power(rC, 2)
);
model.AddGoal("Goal", GoalKind.Minimize, goal);
var solution = solver.Solve();
var q = solution.Quality;
double x = decisionX.GetDouble();
double y = decisionY.GetDouble();
solution.GetNext();
x = decisionX.GetDouble();
y = decisionY.GetDouble();
此代碼的工作,但返回{0.0}作爲LocalOptimal溶液,而最佳是{2,2}(I檢查,GoalFunction爲{2,2}以及用於高得多的值{0返回0, 0},也許{0,0}的出發點時,決定是Domain.Real。
Solution.GetNext()改變不了什麼。
decisionX = new Decision(Domain.RealRange(-10, 10), "X");
decisionY = new Decision(Domain.RealRange(-10, 10), "Y");
如果我限制域,解決方案是返回{1.9999999984154413,1.9999999990963979}所以我t是正確的。
但爲什麼求解器不能啓動全真實域?仍然不知道
也許有人會回答某一天...我希望,但我在下面的答案是正確的。
是距離標量還是矢量類型?您是否肯定在創建模型時定義了A,B和C?在'GoalFunction'中,您用_dsA_減去_rA_,_rB_和_rC_,而在您重寫的代碼中,分別用_dsA_,_dsB_和_dsC_進行減法。這只是一個錯字嗎? –
我已經應用了_GoalFunction_,因爲您已經重寫了它,但用編譯時雙常量替換了A.Location.X,...,dsA ...。當我執行時,我會得到一個合理的答案。如果您尚未這樣做,請確保在定義rA,rB和rC之前定義了A,B,C,dsA,dsB和dsC。 –