回朔法 - 求解最小机器重量设计问题

题目

 

设某一机器由n个部件组成,部件编号为1~n,每一种部件都可以从m个供应商处购得,供应商编号为1~m。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。对于给定的机器部件重量和机器部件的价格,计算总价不超过cost的最小重量机器设计,要求在同一个供应商处最多只购得一个部件。

输入描述

第1行输入3个整数,n、m、cost,接下来n行输入w[i][j](每行m个整数),最后n行输入c[i][j](每行m个整数),1<=n,m<=100。

输出描述

输出的第一行包括n个整数,表示每个对应的供应商编号,第2行为对应的重量。

输入样例

3 3 7

1 2 3

3 2 1

2 3 2

1 2 3

5 4 2

2 1 2

输出样例

1 3 1

4

代码

#include<iostream>
#include<stdio.h>

using namespace std;

int w[100][100];//w[i][j]为第i个零件在第j个供应商的重量
int c[100][100];//c[i][j]为第i个零件在第j个供应商的价格
int bestx[100];//bestx[i]表示一次搜索到底后的最优解,用来存放第i个零件的供应商,
int x[100];//x[i]临时存放第i个零件的供应商
int cw = 0, cc = 0, bestw = 10000;
int cost;//限定价格
int n;//部件数
int m;//供应商数

void Backtrack(int t)
{
    int j;
    if (t > n)//搜索到叶子结点,一个搜索结束,所有零件已经找完
    {
        bestw = cw;//当前最小重量
        for (j = 1; j <= n; j++)
            bestx[j] = x[j];
    }
    else
    {
        for (j = 1; j <= m; j++)
        {
            if (cc + c[t][j] <= cost && cw + w[t][j] < bestw)
            {
                x[t] = j;
                cc += c[t][j];
                cw += w[t][j];
                Backtrack(t + 1);
                cc -= c[t][j];
                cw -= w[t][j];
            }
        }
    }
}

int main()
{
    //cout << "-----------------------------------" << endl;
    int i, j;
    //cout << "请输入部件数:";
    cin >> n;
    //cout << endl << "请输入供应商数:";
    cin >> m;
    //cout << endl << "请输入限定价格:";
    cin >> cost;
    //cout << endl << "-----------------------------------" << endl;

    //cout << "请输入各部件的在不同供应商的重量:" << endl;
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= m; j++)
        {
            cin >> w[i][j];
            // cout << "w[" << i << "][" << j << "] = " << w[i][j] << endl;
        }
        cout << endl;
    }

    //cout << endl << "-----------------------------------" << endl;

    //cout << "请输入各部件的在不同供应商的价格:" << endl;
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= m; j++)
        {
            cin >> c[i][j];
            // cout << "c[" << i << "][" << j << "] = " << c[i][j] << endl;
        }
        cout << endl;
    }

    
    Backtrack(1);
    //cout << "每个部件的供应商:" << endl;
    //cout << endl << "-----------------------------------" << endl;
    for (i = 1; i <= n; i++)
        cout << bestx[i] << ' ';
    cout << endl;
    cout << bestw;
    cout << endl;
    system("pause");
    return 0;
}

以下为我的微信公众号:技术经理的成长

会不定期进行更新,欢迎关注

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
0-1背包问题是一个经典的动态规划问题,可以用回溯求解。以下是算设计: 1. 定义一个最大价值 max_val,初始值为0;定义一个当前价值 cur_val,初始值为0。 2. 定义一个回溯函数 backtrack(cur_weight, cur_val, items, values, weights, max_weight),其中: - cur_weight:当前背包已经装入的物品的重量- cur_val:当前背包已经装入的物品的价值; - items:已经选择的物品; - values:每个物品对应的价值; - weights:每个物品对应的重量- max_weight:背包的最大承重。 3. 在回溯函数中,首先判断当前背包的重量是否超过了最大承重,若超过则返回。 4. 然后判断当前价值是否大于最大价值,若大于则更新最大价值。 5. 接下来进行回溯,对于每一个物品,分别进行选择和不选择两种情况: - 若选择该物品,则将该物品的重量和价值加入到 cur_weight 和 cur_val 中,同时将该物品加入到 items 中,并继续向下执行回溯函数; - 若不选择该物品,则直接跳过该物品,继续向下执行回溯函数。 6. 回溯结束后,返回最大价值。 以下是Python代码实现: ```python def backtrack(cur_weight, cur_val, items, values, weights, max_weight): global max_val if cur_weight > max_weight: return if cur_val > max_val: max_val = cur_val for i in range(len(values)): if i not in items: items.append(i) backtrack(cur_weight + weights[i], cur_val + values[i], items, values, weights, max_weight) items.remove(i) def knapsack_01(values, weights, max_weight): global max_val max_val = 0 items = [] backtrack(0, 0, items, values, weights, max_weight) return max_val ``` 可以使用以下代码进行测试: ```python values = [6, 10, 12] weights = [1, 2, 3] max_weight = 5 print(knapsack_01(values, weights, max_weight)) # 输出:22 ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小爱玄策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值