alpha-beta剪枝测试题

 

 

 

 

 

 

 

 

Java代码:

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    private static ArrayList<String> cutpath = new ArrayList<>();

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        ArrayList<Node> nodelist = new ArrayList<Node>();

        for (int i = 0; i < n; i++) {
            int id = sc.nextInt();
            int val = sc.nextInt();
            int pid = sc.nextInt();
            Node node = new Node(id, val, pid);
            if (id == 1) {
                node.flag = true;
            } else if (nodelist.get(pid - 1).flag) {
                node.flag = false;
            } else {
                node.flag = true;
            }
            nodelist.add(node);
            if (pid != -1) {
                nodelist.get(pid - 1).childid.add(id);
            }

        }
        sc.close();

        go(nodelist);

        for (int i = 0; i < nodelist.get(0).childid.size(); i++) {
            if (nodelist.get(0).val == nodelist.get(nodelist.get(0).childid.get(i) - 1).val) {
                System.out.println(
                        "1 " + nodelist.get(nodelist.get(0).childid.get(i) - 1).id + " " + nodelist.get(0).val);
                break;
            }
        }
        for (String s : cutpath) {
            System.out.println(s);
        }
    }

    public static void go(ArrayList<Node> nodelist) {
        Node root = nodelist.get(0);
        dfs(root, nodelist);
        
    }

    public static int dfs(Node node, ArrayList<Node> nodelist) {
        if (!node.childid.isEmpty()) {// 非叶子结点
            if (node.noused) {
                if (node.flag) {
                    node.val = -999;
                } else {
                    node.val = 999;
                }
                node.noused = false;
            }
            int s = node.childid.size();

            // 遍历子结点
            for (int i = 0; i < s; i++) {
            /**
                       * 如果是极大结点(flag==true),从子节点获得的值大于兄弟结点,则后续子节点不必再遍历
                       * 如果是极小结点(flag==false),从子节点获得的值小于兄弟结点,同样剪枝 剪枝即输出该结点与子节点的序号 若是极大结点再输出beta
                       * 极小结点输出arlfa 然后continue; if(cut) { continue; }
            * 
            */
                // 该结点不是根节点
                if (node.parentid != -1) {
                    // 该结点无兄弟结点,则与爷结点的兄弟结点相比
                    int gpid=1;
                    if(node.id>7){
                        gpid = nodelist.get(nodelist.get(node.parentid - 1).parentid - 1).id;
                    }
                    boolean existgp=false;
                    if (node.id>7 && nodelist.get(node.parentid - 1).childid.size() == 1 && nodelist.get(nodelist.get(gpid-1).parentid-1).childid.get(0)!=gpid) {
                        existgp=true;
                    }
                    // 若是极大结点
                    if (node.flag) {
                        // 若该结点值大于之前任一兄弟结点,则不必再遍历该结点的子节点
                        boolean cut = false;
                        for (int j = 0; j < nodelist.get(node.parentid - 1).childid.indexOf(node.id); j++) {
                            
                            if (node.val > nodelist.get(nodelist.get(node.parentid - 1).childid.get(j) - 1).val) {
                                cut = true;
                                break;
                            }
                        }
                        if (existgp && nodelist.get(node.parentid - 1).childid.size() == 1 && nodelist.get(nodelist.get(gpid-1).childid.get(0)-1).id!=gpid) {
                            if(node.val>nodelist.get(nodelist.get(nodelist.get(gpid-1).parentid-1).childid.get(0)-1).val)
                            {
                                cut=true;
                            }
                        }
                        if (cut) {
                            cutpath.add(node.id + " " + node.childid.get(i) + " beta");
                            continue;
                        }
                    } else {
                        // 若该结点值小于之前任一兄弟结点,则不必再遍历该结点的子节点
                        boolean cut = false;
                        for (int j = 0; j < nodelist.get(node.parentid - 1).childid.indexOf(node.id); j++) {
                            if (node.val < nodelist.get(nodelist.get(node.parentid - 1).childid.get(j) - 1).val) {
                                cut = true;
                                break;
                            }
                        }
                        if (existgp && nodelist.get(node.parentid - 1).childid.size() == 1 && nodelist.get(nodelist.get(gpid-1).childid.get(0)-1).id!=gpid) {
                            if(node.val<nodelist.get(nodelist.get(nodelist.get(gpid-1).parentid-1).childid.get(0)-1).val)
                            {
                                cut=true;
                            }
                        }
                        if (cut) {
                            cutpath.add(node.id + " " + node.childid.get(i) + " alpha");
                            continue;
                        }
                    }
                }

                int k = dfs(nodelist.get(node.childid.get(i) - 1), nodelist);

                // 根据从子节点得到的信息,更改该结点的值
                if (node.flag) {
                    if (k > node.val) {
                        node.val = k;
                    }
                } else {
                    if (k < node.val) {
                        node.val = k;
                    }
                }
               
            }
            return node.val;
        } else {// 叶子结点
            return node.val;
        }
    }
}

class Node {
    public boolean noused = true;
    public boolean flag;
    public int parentid;
    public int id;
    public int val;
    public ArrayList<Integer> childid = new ArrayList<>();

    public Node() {
    }

    public Node(int id, int val, int pid) {
        this.id = id;
        this.val = val;
        this.parentid = pid;
    }
}

  

测试样例和输出:

39
1 0 -1
2 0 1
3 0 1
4 0 2
5 0 2
6 0 3
7 0 3
8 0 4
9 0 4
10 0 5
11 0 5
12 0 5
13 0 5
14 0 6
15 0 6
16 0 7
17 0 7
18 0 8
19 5 8
20 -3 9
21 3 9
22 3 10
23 -3 11
24 0 11
25 2 11
26 2 12
27 -3 12
28 0 12
29 -2 13
30 3 13
31 5 14
32 4 14
33 1 14
34 -3 15
35 0 15
36 6 16
37 8 16
38 9 17
39 -3 17

样例输出
1 3 1
9 21 alpha
5 11 beta
5 12 beta
5 13 beta
15 35 alpha
7 17 beta

  

posted @ 2021-05-01 13:53  梵蒂冈宝石  阅读(843)  评论(1编辑  收藏  举报