贪心算法之背包问题

概念

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。
对于背包物品总价值最大问题,简单来说,在得知每个物品的价格和重量时,计算出每个物品的权值(价格除于质量),把权值大的先放到包中,然后根据权值大小依次放入。

代码和解释

JAVA

先定义一个物品类

public class Bag {
    public int weight;//重量
    public int value;//价值
    public double wi;//权重
    public String pid;//背包名称

    public Bag(int weight, int value, String pid) {
        this.weight = weight;
        this.value = value;
        this.pid = pid;
        this.wi=(double)value/weight;

    }
}

再定义一个类,里面定义一个排序方法,排序方法根据权值的大小的每个物品排序

public class dome {
    //选择排序将数组中的bag按权重排序
    public static void sort(Bag[] p) {
        Bag t;
        for (int i = 0; i < p.length; i++) {
            int max = i;
            t = p[i];
            for (int j = i; j < p.length; j++) {
                if (t.wi < p[j].wi) {
                    t = p[j];
                    max = j;
                }
            }
            t = p[i];
            p[i] = p[max];
            p[max] = t;
        }
    }

    //背包问题(贪心算法)
    public static void bq(Bag[] p, int k, int w, double v) {
        if (p[k].weight < w) {
            v = v + p[k].value;
            System.out.println(p[k].pid + "全部装入,当前背包价值为" + v);
            w = w - p[k].weight;
            bq(p, k + 1, w, v);
        } else {
            double a = w * p[k].wi;//当前价值
            v = v + a;
            System.out.println(p[k].pid + "装入了" +
                    ((double) w / p[k].weight) + ",当前背包价值为" + v);
        }


    }
}

最后写一个main方法测试

import java.util.Scanner;

public class tanxin {
    public static void main(String[] args) {
        System.out.println("请输入背包的容量w和物品的个数n:");
        Scanner scanner = new Scanner(System.in);
        int w = scanner.nextInt();
        int n = scanner.nextInt();
        Bag[] p=new Bag[n];
        System.out.println("请依次输入各个物品的重量w和价值v和名称s");
        int weigth;
        int value;
        String pid;
        for(int i=0;i<n;i++){
            weigth=scanner.nextInt();
            value = scanner.nextInt();
            pid = scanner.next();
            p[i]=new Bag(weigth,value,pid);
        }
        dome.sort(p);
        dome.bq(p,0,w,0.0);
        for(int i=0;i<n;i++){
            System.out.println(p[i].wi+" "+p[i].pid);
        }
    }
}

运行结果

在这里插入图片描述

PYTHON

# 完全背包问题,贪心算法
import time
class goods:
  def __init__(self, goods_id, weight=0, value=0):
    self.id = goods_id
    self.weight = weight
    self.value = value
# 不适用于0-1背包
def knapsack(capacity=0, goods_set=[]):
  # 按单位价值量排序
  goods_set.sort(key=lambda obj: obj.value / obj.weight, reverse=True)
  result = []
  for a_goods in goods_set:
    if capacity < a_goods.weight:
      break
    result.append(a_goods)
    capacity -= a_goods.weight
  if len(result) < len(goods_set) and capacity != 0:
    result.append(goods(a_goods.id, capacity, a_goods.value * capacity / a_goods.weight))
  return result
some_goods = [goods(0, 2, 4), goods(1, 8, 6), goods(2, 5, 3), goods(3, 2, 8), goods(4, 1, 2)]
start_time = time.clock()
res = knapsack(6, some_goods)
end_time = time.clock()
print('花费时间:' + str(end_time - start_time))
for obj in res:
  print('物品编号:' + str(obj.id) + ' ,放入重量:' + str(obj.weight) + ',放入的价值:' + str(obj.value), end=',')
  print('单位价值量为:' + str(obj.value / obj.weight))

运行结果
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值