【算法设计与分析】实验五分支限界法(附源代码)

一、上机目的

1、通过分支限界法的示例程序进一步理解分支限界法的基本思想;
2、运用分支限界法解决实际问题,进一步加深对分支限界法的理解和运用

二、上机内容与要求

1、分析并掌握“单源最短路径” 问题的分支限界法求解方法;
2、练习使用分支限界法求解“装载”问题;

三、上机步骤

1.理解分支限界法思想和算法示例;
2.上机输入和调试算法示例程序;
3.理解实验题的问题要求;
4.上机输入和调试自己所编的实验题程序;
5.验证并分析实验题的实验结果;
6.整理出实验报告;

四、上机结果

1、将课本6.2节单源最短路径算法改为程序,并进行测试和验证

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

class ArcCell {
    int adj;  // 保存权值
    int info; // 存储最短路径长度
}

public class GraphPath {

    static ArcCell[][] AdjMatrix = new ArcCell[100][100];
    static VerType[] vexs = new VerType[100];
    static int vexnum;
    static int arcnum;
    static Queue<Integer> q = new LinkedList<>();

    static class VerType {
        int data;
        int length;
    }

    static void CreateGraph() {
        Scanner scanner = new Scanner(System.in);
        int m, n, t;
        System.out.print("输入顶点数和弧数:");
        vexnum = scanner.nextInt();
        arcnum = scanner.nextInt();
        System.out.print("输入顶点:");
        for (int i = 1; i <= vexnum; i++) {
            vexs[i] = new VerType();
            vexs[i].data = scanner.nextInt();
            vexs[i].length = 10000;
        }

        for (int i = 1; i <= vexnum; i++)
            for (int j = 1; j <= vexnum; j++) {
                AdjMatrix[i][j] = new ArcCell();
                AdjMatrix[i][j].adj = 0;
            }

        System.out.println("输入弧及权重:");
        for (int i = 1; i <= arcnum; i++) {
            m = scanner.nextInt();
            n = scanner.nextInt();
            t = scanner.nextInt();
            AdjMatrix[m][n].adj = 1;
            AdjMatrix[m][n].info = t;
        }
    }

    static int NextAdj(int v, int w) {
        for (int i = w + 1; i <= vexnum; i++)
            if (AdjMatrix[v][i].adj != 0)
                return i;
        return 0; // not found;
    }

    static void ShortestPaths(int v) {
        int k = 0; // 从首个节点开始访问
        int t;
        vexs[v].length = 0;
        q.offer(vexs[v].data);
        while (!q.isEmpty()) {
            t = q.poll();
            k = NextAdj(t, k);
            while (k != 0) {
                if (vexs[t].length + AdjMatrix[t][k].info <= vexs[k].length) {
                    vexs[k].length = vexs[t].length + AdjMatrix[t][k].info;
                    q.offer(vexs[k].data);
                }
                k = NextAdj(t, k);
            }
        }
    }

    static void Print() {
        for (int i = 1; i <= vexnum; i++)
            System.out.println(vexs[i].data + "------" + vexs[i].length);
    }

    public static void main(String[] args) {
        CreateGraph();
        ShortestPaths(1);
        Print();
    }
}

在这里插入图片描述

2、将课本6.3节装载问题改为程序,并进行测试和验证。

import java.util.PriorityQueue;
import java.util.Scanner;

class MaxHeapQNode {
    MaxHeapQNode parent;  // 父节点
    int lchild;           // 左节点: 1; 右节点: 0
    int weight;           // 总重量
    int lev;              // 层次
}

class MaxLoading {
    static int n;
    static int c;
    static int bestw;
    static int[] w;
    static int[] bestx;

    public static void main(String[] args) {
        InPut();
        MaxLoading();
        OutPut();
    }

    static void InPut() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Input1:");
        n = scanner.nextInt();
        System.out.println("Input2:");
        c = scanner.nextInt();
        System.out.println("Input3:");
        w = new int[n + 1];
        bestx = new int[n + 1];
        for (int i = 1; i <= n; ++i)
            w[i] = scanner.nextInt();
    }

    static void AddAliveNode(PriorityQueue<MaxHeapQNode> q, MaxHeapQNode E, int wt, int i, int ch) {
        MaxHeapQNode p = new MaxHeapQNode();
        p.parent = E;
        p.lchild = ch;
        p.weight = wt;
        p.lev = i + 1;
        q.add(p);
    }

    static void MaxLoading() {
        PriorityQueue<MaxHeapQNode> q = new PriorityQueue<>((a, b) -> Integer.compare(b.weight, a.weight));
        // 定义剩余重量数组r
        int[] r = new int[n + 1];
        r[n] = 0;
        for (int j = n - 1; j > 0; --j)
            r[j] = r[j + 1] + w[j + 1];
        int i = 1;
        MaxHeapQNode E = new MaxHeapQNode();
        int Ew = 0;
        while (i != n + 1) {
            if (Ew + w[i] <= c) {
                AddAliveNode(q, E, Ew + w[i] + r[i], i, 1);
            }
            AddAliveNode(q, E, Ew + r[i], i, 0);

            // 取下一节点
            E = q.poll();
            i = E.lev;
            Ew = E.weight - r[i - 1];
        }
        bestw = Ew;
        for (int j = n; j > 0; --j) {
            bestx[j] = E.lchild;
            E = E.parent;
        }
    }

    static void OutPut() {
        System.out.println("最优装载量为 " + bestw);
        System.out.println("装载的物品为 ");
        for (int i = 1; i <= n; ++i)
            if (bestx[i] == 1)
                System.out.print(i + " ");
    }
}

在这里插入图片描述

在这里插入图片描述

  • 15
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
背包问题是一个经典的组合优化问题,它的目标是在给定的一组物品中选择一些物品放入一个容量为W的背包中,使得背包中物品的总价值最大。分支限界法是解决背包问题的一种常用算法,它通过不断地分解问题,将问题空间划分为多个子问题,并对每个子问题进行求解,最终得到原问题的最优解。 下面是背包问题分支限界法代码算法设计与分析: 1. 算法设计 (1)定义节点类Node,包含以下成员变量: - weight:当前节点已经装入背包的物品重量; - value:当前节点已经装入背包的物品价值; - bound:当前节点的价值上界; - level:当前节点所在的层数; - path:当前节点所在的路径。 (2)定义优先队列Q,用于存储待扩展的节点。 (3)初始化根节点,并将其加入队列Q中。 (4)循环执行以下步骤: - 从队列Q中取出一个节点; - 如果该节点的价值上界小于当前最优解,则舍弃该节点; - 如果该节点是叶子节点,则更新当前最优解; - 否则,生成该节点的左右子节点,并将它们加入队列Q中。 (5)输出当前最优解。 2. 算法分析 背包问题分支限界法的时间复杂度为O(2^n),其中n为物品的数量。由于该算法需要对每个节点进行价值上界的计算,因此空间复杂度为O(n)。在实际应用中,该算法的效率受到物品数量和背包容量的限制,当物品数量较大或背包容量较小时,该算法的效率会受到较大影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值