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

如何用Prim算法编写谓词实现带权无向图的最小生成树?

Implementing Prim's Algorithm for Minimum Spanning Tree in Prolog

Great start on your Prim's implementation—you've got the core initialization right! Let's fill in the missing pieces to make this work end-to-end. Prim's algorithm works by growing the MST one edge at a time: starting from an initial node, we repeatedly pick the smallest-weight edge that connects a visited node to an unvisited one, adding that edge to the MST and marking the new node as visited until all nodes are included.

First, let's adjust your initial predicate to track state more clearly—we'll need to keep track of the current MST edges, the set of visited nodes, and the set of unvisited nodes as we recurse:

% Entry point: Fetch all nodes, pick a starting node (last one as you did), initialize state
mst(ResultMST) :-
    nodes(AllNodes),
    last(AllNodes, StartNode),
    delete(AllNodes, StartNode, Unvisited),
    mst(ResultMST, [], [StartNode], Unvisited). % Current MST is empty, visited starts with our initial node

Next, we'll add the base case for when we're done—when there are no unvisited nodes left, our current MST is the final result:

% Base case: No unvisited nodes left, MST is complete
mst(FinalMST, FinalMST, _, []).

Now, we need two helper predicates: one to find all valid candidate edges (connecting visited to unvisited nodes), and another to pick the smallest-weight edge from those candidates.

First, let's assume you have an edge/3 predicate defined for your graph (storing undirected edges with weights—e.g., edge(a,b,2) means a 2-weight edge between a and b). Here's the candidate edge finder:

% Helper: Find all edges connecting a visited node to an unvisited node, with their weight
candidate_edge(Visited, Unvisited, (From-To, Weight)) :-
    member(From, Visited),
    member(To, Unvisited),
    edge(From, To, Weight).

Then, a predicate to find the minimum-weight edge from a list of candidates:

% Helper: Recursively find the edge with the smallest weight in a list
min_edge([Edge], Edge).
min_edge([(N1-N2, W1)|Rest], MinEdge) :-
    min_edge(Rest, (N1'-N2', W2)),
    (W1 =< W2 -> MinEdge = (N1-N2, W1) ; MinEdge = (N1'-N2', W2)).

Finally, the recursive step that does the heavy lifting—collecting candidates, picking the smallest edge, updating our visited/unvisited sets, and adding the edge to the MST:

% Recursive step: Expand the MST by adding the smallest valid edge
mst(ResultMST, CurrentMST, Visited, Unvisited) :-
    % Gather all possible candidate edges
    findall(Candidate, candidate_edge(Visited, Unvisited, Candidate), Candidates),
    % Pick the edge with the smallest weight
    min_edge(Candidates, MinEdge),
    MinEdge = (From-To, _),
    % Add this edge to our current MST
    append(CurrentMST, [MinEdge], UpdatedMST),
    % Move the newly visited node to the visited set
    delete(Unvisited, To, UpdatedUnvisited),
    append(Visited, [To], UpdatedVisited),
    % Recurse with the updated state
    mst(ResultMST, UpdatedMST, UpdatedVisited, UpdatedUnvisited).

To test this, you'll need to define your graph's nodes and edges. Here's an example you can use:

% Example graph definition
nodes([a, b, c, d, e]).
edge(a, b, 2).
edge(a, c, 3).
edge(b, c, 1).
edge(b, d, 1).
edge(b, e, 4).
edge(c, e, 2).
edge(d, e, 3).

If you run mst(T). with this example, you'll get a result like [(b-c,1), (b-d,1), (a-b,2), (c-e,2)] (the order might vary slightly depending on Prolog's backtracking, but the total weight will be the minimum possible for the MST).

A couple of notes to keep in mind:

  • This implementation assumes your graph is connected—if it's disconnected, the predicate will fail (which is correct, since disconnected graphs don't have a single spanning tree).
  • Since the graph is undirected, we don't need to handle reverse edges explicitly; the candidate_edge predicate will find them, but the min edge selection will still work correctly.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:04:47