1. 程式人生 > >動態規劃之揹包問題原理詳細推導及其實現

動態規劃之揹包問題原理詳細推導及其實現

貪心演算法:

(1)      給定n個物品,物品價值分別為P1P2,…,Pn,物品重量分別W1W2, …, Wn,揹包容量為M。每種物品可部分裝入到揹包中。輸出X1X2,…,Xn,0<Xi<1, 使得 最大,且 <M。試設計一個演算法求解該問題,分析演算法的正確性.

解:

  設計思路:首先將n個物品按單位價值從大到小排序,每次取剩餘物品中單位價值最大的物品放入揹包,若揹包的容量足夠則放入整個物品,否則放入物品的一部分。

  最優子結構性質


貪心選擇性:


綜上所述,該演算法具有貪心選擇性。

演算法的原始碼如下:

// Test.cpp : 定義控制檯應用程式的入口點。
#include "stdafx.h"
#include <iostream>
#include <algorithm>
#define MAX_NUM 1000
using namespace std;

struct Goods //info of goods定義物品資訊結構體
{
    int weight;// the weight of goods重量
    int value;// the value of goods價值
    double ValPerWei;// value per weight權重
    double load; //物品裝入揹包的部分的係數(例如上圖中物品全部裝入則load為1,裝入10/20則load為0.5)
};
int cmp( Goods const &a, Goods const &b)//定義sort函式的比較函式
{
    if(a.ValPerWei<b.ValPerWei) return 0;
    else return 1;
}
void Greedy(Goods g[],int good_num, int content)//貪心演算法
{
    for(int i=0; i<good_num; i++)
    {
        if(content>g[i].weight)//如果揹包足夠裝下整個物品
        {
            content-=g[i].weight;
            g[i].load=1;
        }
        else if(content>0){//如果揹包不足以裝下整個物品
            g[i].load=(double)content/g[i].weight;//計算物品裝入揹包的部分
            content=0;//揹包容量置0
            return;//程式結束,返回
        }
    }
}
int main()
{
    int goods_num;
    int bagvol;
    double total_value=0;
    double total_weight=0;
	Goods *G;
    cout<<"請輸入揹包的容量:"<<endl;
    cin>>bagvol;
    cout<<"請輸入商品的種類:"<<endl;
    cin>>goods_num;
   // Goods G[goods_num+1];
	G= new Goods[goods_num+1];
    cout<<"請輸入商品的重量和價值:"<<endl;
    for(int i=0; i<goods_num; i++)
    {
        cin>>G[i].weight>>G[i].value;//輸入重量價值
        G[i].ValPerWei=(double)G[i].value/G[i].weight;//計算權重
        G[i].load=0;//load置0
    }

    sort (G,G+goods_num,cmp);//sort by ValPerWei

    Greedy(G,goods_num,bagvol);
    for(int i=0;i<goods_num;i++)//output the info of goods
    {
        if(G[i].load==0.0)break;//如果檢測到物品未被裝入揹包,則推出迴圈

        total_value+=(G[i].value*G[i].load);//裝入揹包的物品總價值
        total_weight+=(G[i].weight*G[i].load);//裝入揹包的物品總重量
    }
    cout<<"揹包容量為: "<<bagvol<<endl;//輸出揹包容量
    cout<<"裝入物品的總重量為: "<<total_weight<<endl;//輸出裝入物品的總重量
    cout<<"裝入物品的最大價值為: "<<total_value<<endl;//輸出裝入物品的總價值
	return 0;

}

相關推薦

動態規劃揹包問題原理詳細推導及其實現

貪心演算法:(1)      給定n個物品,物品價值分別為P1,P2,…,Pn,物品重量分別W1,W2, …, Wn,揹包容量為M。每種物品可部分裝入到揹包中。輸出X1,X2,…,Xn,0<Xi<1, 使得

動態規劃揹包問題和區間模型--Java實現

揹包問題描述:給定n個重量為w1,w2...wn、價值為v1,v2...vn的物品和一個承重量為W的揹包,求這些物品中最優價值的一個子集,並且要能夠裝到揹包中。 結論:1.在不包括第i個物品的子集中,最優子集的價值是Value[i-1][j]. 2.在包括第i個物品的子

動態規劃揹包問題

1. 一維揹包問題 0-1揹包問題 給定一個載重量為CCC的揹包,有nnn個物品,每個物品的重量為wiw_{i}wi​,每個物品的價值為viv_{i}vi​,如何往揹包中裝物品使得揹包中的總價值最大化。 maxV=Σvixis.t.Σwixi≤Cxi=0or1

動態規劃揹包問題及輸出揹包具體方案

參考:https://blog.csdn.net/qq_27139155/article/details/79727991 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=20; 4 int n,b;

動態規劃揹包問題(C語言)

動態規劃 動態規劃(英語:Dynamic programming,簡稱DP)是一種通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。 動態規劃常常適用於有重疊子問題和最優子結構性質的問題 動態規劃思想大致上為:若要解一個給定問題,我們需要解其不同

【機器學習】演算法原理詳細推導實現(一):線性迴歸

【機器學習】演算法原理詳細推導與實現(一):線性迴歸 今天我們這裡要講第一個有監督學習演算法,他可以用於一個迴歸任務,這個演算法叫做 線性迴歸 房價預測 假設存在如下 m 組房價資料: 面積(m^2) 價格(萬元) 82.35 193 65.00 213 114.20 255 75.

【機器學習】演算法原理詳細推導實現(二):邏輯迴歸

【機器學習】演算法原理詳細推導與實現(二):邏輯迴歸 在上一篇演算法中,線性迴歸實際上是 連續型 的結果,即 \(y\in R\) ,而邏輯迴歸的 \(y\) 是離散型,只能取兩個值 \(y\in \{0,1\}\),這可以用來處理一些分類的問題。 logistic函式 我們可能會遇到一些分類問題,例如想要劃

【機器學習】演算法原理詳細推導實現(三):樸素貝葉斯

【機器學習】演算法原理詳細推導與實現(三):樸素貝葉斯 在上一篇演算法中,邏輯迴歸作為一種二分類的分類器,一般的迴歸模型也是是判別模型,也就根據特徵值來求結果概率。形式化表示為 \(p(y|x;\theta)\),在引數 \(\theta\) 確定的情況下,求解條件概率 \(p(y|x)\) 。通俗的解釋為:

【機器學習】演算法原理詳細推導實現(四):支援向量機(上)

【機器學習】演算法原理詳細推導與實現(四):支援向量機(上) 在之前的文章中,包括線性迴歸和邏輯迴歸,都是以線性分界線進行分割劃分種類的。而本次介紹一種很強的分類器【支援向量機】,它適用於線性和非線性分界線的分類方法。 函式間隔概念 為了更好的理解非線性分界線,區別兩種分界線對於分類的直觀理解,第一種直觀理解

【機器學習】演算法原理詳細推導實現(五):支援向量機(下)

【機器學習】演算法原理詳細推導與實現(五):支援向量機(下) 上一章節介紹了支援向量機的生成和求解方式,能夠根據訓練集依次得出\(\omega\)、\(b\)的計算方式,但是如何求解需要用到核函式,將在這一章詳細推導實現。 核函式 在講核函式之前,要對上一章節得到的結果列舉出來。之前需要優化的凸函式為: \[

【機器學習】演算法原理詳細推導實現(六):k-means演算法

【機器學習】演算法原理詳細推導與實現(六):k-means演算法 之前幾個章節都是介紹有監督學習,這個章節介紹無監督學習,這是一個被稱為k-means的聚類演算法,也叫做k均值聚類演算法。 聚類演算法 在講監督學習的時候,通常會畫這樣一張圖: 這時候需要用logistic迴歸或者SVM將這些資料分成正負兩

【機器學習】演算法原理詳細推導實現(七):決策樹演算法

# 【機器學習】演算法原理詳細推導與實現(七):決策樹演算法 在之前的文章中,對於介紹的分類演算法有[邏輯迴歸演算法](https://www.cnblogs.com/TTyb/p/10976291.html)和[樸素貝葉斯演算法](https://www.cnblogs.com/TTyb/p/109890

動態規劃完全揹包問題(java實現

之前寫了01揹包問題,現在寫完全揹包問題。和01揹包不同的是,完全揹包不限定某種物品的件數,可以裝0,1,2,...,而01揹包只有裝與不裝的區別。但是思考問題的方式還是一樣的,我就其中的最大值。詳細程式碼和註釋見下面程式碼。 package backpack; /* f[i][v]:前i件物

動態規劃0-1揹包問題(POJ3624)

有N件物品和一個容積為M的揹包。第i件物品的體積w[i],價值是d[i]。求解將哪些物品裝入揹包可使價值總和最大。每種物品只有一件,可以選擇放或者不放。(N<=3500,M<=130000)。 解題思路: 用F[i][j]表示取前i種物品,使它們總體積不超過j的最優取法取

【leetcode】動態規劃01揹包問題

先學會手動填動態規劃的表  後面的顏色塊值是根據前面的顏色塊值計算出來的,不懂就留言 #include<iostream> #include<vector> using namespace std; int Knapsack(vector<i

再學動態規劃 完全揹包

暴力搜尋 考慮當前index 拿1張,2張,…時候,從index+1開始的最小張數。相加即可: import sys class Solution(object): def get_smal

動態規劃0-1揹包問題

問題: 物品集合s={1,2,3,4,…,n},物品i的重量為wi,其價值為vi,揹包的容量(最大載重量)為W,如何裝使物品價值最大。(物品不能分割) 分析: p(i,j)是揹包容量為j,可選物品為i(i+1,…,n)時的最優解 (“將前i個物品放入容量為j的揹

動態規劃01揹包問題及leetcode例項

01揹包問題 這篇文章講的很清楚,我這裡就不贅述了。 leetcode problem 416 描述 Given a non-empty array containing only positive integers, find if th

詳細動態規劃解析——揹包問題

動態規劃的定義 要解決一個複雜的問題,可以考慮先解決其子問題。這便是典型的遞迴思想,比如最著名的斐波那契數列,講遞迴必舉的例子。 斐波納契數列的定義如下:F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*) 用遞迴

動態規劃0-1揹包問題,鋼條切割

動態規劃 首先說說動態規劃:動態規劃與分治法相似,都是組合子問題的解來解決原問題的解,與分治法的不同在於:分治法的子問題是相互獨立存在的,而動態規劃應用於子問題重疊的情況。 設計動態規劃演算法的步驟: 1、刻畫一個最優解的結構特徵 2、遞迴地定義最優解的