You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Prolog路径规划应用开发求助:最便宜路径实现故障

修复你的Prolog最便宜路径实现问题

看起来你在搭建基于Prolog的路径规划系统时,最便宜路径的功能出了问题。我来帮你拆解问题根源,再给出修正后的完整实现:

问题分析

你的代码里有几个核心问题导致功能失效:

  1. 路径与成本计算不匹配:path/3生成的是纯节点列表(比如[gdansk, sopot, gdynia]),但path_cost/2试图从这个列表里匹配train事实——节点列表根本不包含交通工具的成本信息,自然无法计算。
  2. 忽略飞机成本:path_cost/2只处理了火车的费用,完全漏掉了飞机的成本项。
  3. 成本结构解析错误:你的train/plane事实里,成本是cena(5)这种结构化数据,直接拿它做sum运算,Prolog无法识别为数值进行计算。

修正后的代码实现

我们需要重构路径的表示逻辑,让它能跟踪每一段行程的成本,同时修正成本计算的逻辑:

1. 保留原有的交通工具事实

% train/plane(name, from, to, departure, arrival, price).
train(p1, gdansk, sopot, odjazd(10:15), przyjazd(10:30), cena(5)).
train(p2, sopot, gdynia, odjazd(11:00), przyjazd(11:30), cena(5)).
train(p3, sopot, gdynia, odjazd(11:15), przyjazd(11:45), cena(5)).
plane(s1, gdansk, warszawa, odlot(16:00), przylot(17:15), cena(300)).
plane(s2, gdansk, wroclaw, odlot(14:00), przylot(15:30), cena(300)).
plane(s3, gdansk, poznan, odlot(18:00), przylot(19:30), cena(200)).

2. 重构路径谓词,跟踪行程段与累计成本

修改path/4,让它生成包含每一段交通工具的路径,并实时累计总成本:

% path(From, To, Path, TotalCost) 
% Path是行程段的列表,TotalCost是该路径的总成本
path(From, To, Path, TotalCost) :-
    path(From, To, [], Path, 0, TotalCost).

% 终止条件:到达目的地,总成本累计完成
path(To, To, _, [], TotalCost, TotalCost).

% 递归条件:找到从当前节点出发的交通工具,前往下一个节点并累计成本
path(From, To, Visited, [Leg|Rest], CurrentCost, TotalCost) :-
    \+ member(From, Visited),  % 避免循环访问同一节点
    dif(From, To),
    % 匹配火车或飞机的行程段,并提取成本数值
    (train(Name, From, Next, Dep, Arr, cena(Cost)) ; plane(Name, From, Next, Dep, Arr, cena(Cost))),
    NewCost is CurrentCost + Cost,  % 累计当前段的成本
    path(Next, To, [From|Visited], Rest, NewCost, TotalCost).

3. 实现最便宜路径查询

现在可以用aggregate_all/3来筛选出总成本最小的路径:

% path_min_cost(From, To, MinCost, OptimalPath)
% 返回从From到To的最便宜路径及其总成本
path_min_cost(From, To, MinCost, OptimalPath) :-
    aggregate_all(min(C, P), path(From, To, P, C), min(MinCost, OptimalPath)).

4. 可选:纯节点路径转换(如果需要)

如果你还是需要得到仅包含节点的路径,可以添加一个辅助谓词:

% path_to_nodes(Path, Nodes) - 将行程段列表转换为纯节点列表
path_to_nodes([], [_]).
path_to_nodes([train(_, From, To, _, _, _)|Rest], [From|Nodes]) :-
    path_to_nodes(Rest, [To|Nodes]).
path_to_nodes([plane(_, From, To, _, _, _)|Rest], [From|Nodes]) :-
    path_to_nodes(Rest, [To|Nodes]).

测试示例

查询从gdansk到gdynia的最便宜路径:

?- path_min_cost(gdansk, gdynia, MinCost, Path).
MinCost = 10,
Path = [train(p1, gdansk, sopot, odjazd(10:15), przyjazd(10:30), cena(5)), train(p2, sopot, gdynia, odjazd(11:00), przyjazd(11:30), cena(5))] ;
MinCost = 10,
Path = [train(p1, gdansk, sopot, odjazd(10:15), przyjazd(10:30), cena(5)), train(p3, sopot, gdynia, odjazd(11:15), przyjazd(11:45), cena(5))].

如果需要纯节点路径:

?- path_min_cost(gdansk, gdynia, MinCost, Path), path_to_nodes(Path, Nodes).
MinCost = 10,
Path = [...],
Nodes = [gdansk, sopot, gdynia] ;
...

后续扩展建议

  • 最快路径:需要解析odjazd/1、przyjazd/1等时间结构,计算每段行程的耗时并累计,再用aggregate_all/3筛选最小总耗时的路径。
  • 限制最晚到达时间的最便宜路径:在递归条件中添加到达时间检查,确保每一段的到达时间不超过限制,同时累计成本。
  • 限制最高价格的最快路径:在递归中检查累计成本不超过上限,同时计算总耗时,筛选最小耗时的路径。

内容的提问来源于stack exchange,提问作者Konrad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:39:27