算法设计与分析实验五:回溯法

一、实验目的

1、深入理解回溯法深度优先搜索策略

2、掌握用回溯法解题的算法框架

3、学习并理解回溯法的设计策略。

二、问题描述

设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得,设wij是从供应商j处购得的部件i的重量,cij是相应的价格。设计一个算法,计算总价格不超过c的最小重量机器设计。

算法设计:对于给定的机器部件重量和机器部件价格,计算总价格不超过d的最小重量机器设计。

  • 输入

由文件input.txt给出输入数据,第1行输入3个正整数n,m和d。接下来的2n行,每行n个数,前n行是c,后n行是w。

3 3 4

1 2 3

3 2 1

2 2 2

1 2 3

3 2 1

2 2 2

  • 输出

将计算的最小重量及每个部件的供应商输出到文件output.txt。

上例输出为

4

1 3 1

  • 数据结构

物理存储结构:顺序存储结构

数据的基本操作:插入,遍历查找

void mw(int i, int n, int m, int c[], int w[], int d, int cc, int cw, int cs[], int *bs);//计算最小重量

算法设计

#include <iostream>

using namespace std;

void mw(int i, int n, int m, int c[], int w[], int d, int cc, int cw, int cs[], int *bs);

int bw;

FILE *test,*answer;

int main()

{

  for(int k=0; k<11; k++)

    {

        int n, m, d;

        string testadd = "./test/machine" + to_string(k) + ".in", answeradd = "./answer/machine" + to_string(k) + ".out";

        test = fopen(&testadd[0], "r"), answer = fopen(&answeradd[0], "r");

        fscanf(test, "%d%d%d", &n, &m, &d);

        int c[n*m], w[n*m], cs[n*m]= {0}, bs[n]= {0};

        bw=10000;

        for(int i = 0; i < n; i++)

        {

            for(int j = 0; j < m; j++)

            {

                fscanf(test,"%d", &c[i*m+j]);

                cs[i*m+j]=0;

            }

        }

        for(int i = 0; i < n; i++)

        {

            for(int j = 0; j < m; j++)

            {

                fscanf(test,"%d", &w[i*m+j]);

            }

        }

        mw(0, n, m, c, w, d, 0, 0, cs, bs);

        int a,an[n];

        int result=1;

        fscanf(answer,"%d",&a);

        printf("%d\n", bw);

        for(int k = 0; k < n; k++)

        {

            printf("%d ", bs[k]);

            fscanf(answer,"%d",&an[k]);

            if(bs[k]!=an[k])

            {

                result=0;

            }

        }

        printf("\n");

        if(result==1)

            cout<<"true"<<endl;

        else

            cout<<"false"<<endl;

    }

    return 0;

}

void mw(int i, int n, int m, int c[], int w[], int d, int cc, int cw, int cs[], int *bs)

{

    if(i == n)

    {

        if(cw < bw)

        {

            bw = cw;

            for(int k = 0; k < n; k++)

            {

                for(int p = 0; p < m; p++)

                {

                    if(cs[k*m+p] == 1)

                        bs[k] = p+1;

                }

            }

        }

        return;

    }

    else

    {

        for(int j = 0; j < m ; j++)

        {

            if(cc + c[i*m+j] <= d)

            {

                if(cw+w[i*m+j]<bw)

                {

                    cc += c[i*m+j];

                    cw += w[i*m+j];

                    cs[i*m+j] = 1;

                    mw(i + 1, n, m, c, w, d, cc, cw, cs, bs);

                    cc -= c[i*m+j];

                    cw -= w[i*m+j];

                    cs[i*m+j] = 0;

                }

            }

        }

    }

}

实验结果

实验心得

通过这次实验我理解了回溯法实际上是一个决策树的遍历过程,是个多叉树的遍历过程,它的基本思想是按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。当问题规模不是很大时,可以采用回溯的方法,递归遍历所有情况,能够找出全局最优解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值