C# 分支定界法 01背包问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 分支定界法 01背包问题相关的知识,希望对你有一定的参考价值。
用C#编程通过分支定界法解决背包问题。急急急。
using System;using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Test01Bag
public partial class Form1 : Form
public Form1()
InitializeComponent();
public class Product
#region 商品类
/// <summary>
/// 商品重量泛型List存储
/// </summary>
private List<int> weight = new List<int>();
public List<int> Weight
get return weight;
set weight = value;
private List<int> value = new List<int>();
/// <summary>
/// 商品价值泛型List存储
/// </summary>
public List<int> Value
get return this.value;
set this.value = value;
private int count;
/// <summary>
/// 商品数量
/// </summary>
public int Count
get
count = weight.Count;
return count;
/// <summary>
/// 添加商品信息
/// </summary>
/// <param name="w">重量</param>
/// <param name="v">价值</param>
/// <returns></returns>
public int setWeightAddValve(int w, int v)
weight.Add(w);
value.Add(v);
return weight.Count;
#endregion
public class Bag
#region 背包类
int[,] help = new int[100, 100];
int[] weight = new int[100];
int[] value = new int[100];
int count;
int temp;
// 背包容量
private int valume;
public int Valume
get return valume;
set valume = value;
private int maxvalue;
public int Maxvalue
get return maxvalue;
set maxvalue = value;
/// <summary>
/// 设定容量temp暂存
/// </summary>
/// <param name="v"></param>
public void setValume(int v)
valume = v;
temp = valume;
/// <summary>
/// 引入数据
/// </summary>
/// <param name="newprd">Product</param>
public void setProduct(Product newprd)
count = newprd.Count;
weight = newprd.Weight.ToArray();
value = newprd.Value.ToArray();
/// <summary>
/// 买商品
/// </summary>
/// <returns></returns>
public int buyproduct()
//初始化help表第一行为零
for (int w = 0; w < valume; w++)
help[0, w] = 0;
for (int i = 1; i <= count; i++)
// //初始化help表第一l列为零
help[i, 0] = 0;
for (int w = 1; w <= valume; w++)
int temp = w - weight[i - 1];
if (weight[i - 1] <= w)
if (value[i - 1] + help[i - 1, temp] > help[i - 1, w])
help[i, w] = value[i - 1] + help[i - 1, temp];
else
help[i, w] = help[i - 1, w];
else
help[i, w] = help[i - 1, w];
maxvalue = help[count, valume];
return maxvalue;
/// <summary>
/// 显示结果买的商品状态存入ArrayList
/// </summary>
/// <returns></returns>
public ArrayList showResult()
ArrayList result = new ArrayList();
if (weight[0] == help[1, temp])
result.Add("Buy!");
else
result.Add("Not Buy!");
if (count >= 2)
for (int i = count; i <= 2; i--)
if (help[i, temp] == help[i - 1, temp])
result.Add("Not Buy!");
else
result.Add("Buy!");
temp = temp - weight[i - 1];
return result;
#endregion
/// <summary>
/// 实例化
/// </summary>
Product newproduct = new Product();
Bag newbag = new Bag();
int i=1;
private void Form1_Load(object sender, EventArgs e)
///初始化
onit();
public void onit()
#region 程序初始化
//清空
newproduct.Value.Clear();
newproduct.Weight.Clear();
newbag.Valume = 0;
lstboxResult.Items.Clear();
#endregion
/// <summary>
/// 存储商品信息函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnAddProduct_Click(object sender, EventArgs e)
#region 添加商品信息
try
int w = Convert.ToInt32(txtWeight.Text);
int v = Convert.ToInt32(txtValue.Text);
newproduct.setWeightAddValve(w, v);
i++;
label1.Text = "请输入商品(" + i.ToString() + ")的体积:";
label3.Text = "请输入商品(" + i.ToString() + ")的价值:";
txtWeight.Text = "";
txtValue.Text = "";
catch
MessageBox.Show("你的输入有错误,请重新输入!");
return;
#endregion
/// <summary>
/// 问题解决函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnToBuy_Click(object sender, EventArgs e)
#region 解决背包问题
try
int i = 1;
int v = Convert.ToInt32(txtValume.Text);
newbag.setValume(v);
txtValume.Text = "";
newbag.setProduct(newproduct);
int x = newbag.buyproduct();
lblMaxvalue.Text = "最大价值为:" + newbag.buyproduct().ToString();
ArrayList result = newbag.showResult();
int f = result.Count;
foreach (string str in result)
string message = "商品" + i.ToString() + "--------" + str;
lstboxResult.Items.Add(message);
i++;
onit();
catch
MessageBox.Show("你的输入有错误,请重新输入!");
return;
#endregion
参考技术A 希望把题目写的更详细一点?
数模常用算法系列--整数线性规划(分枝定界法)整数非线性规划(蒙特卡洛法)
整数线性规划求解----分枝定界法
什么是整数规划?
? 线性规划中的变量(部分或全部)限制为整数时,称为整数规划。若在线性规划模型中,变量限制为整数,则称为整数线性规划。目前所流行的求解整数规划的方法,往往只适用于整数线性规划。目前还没有一种方法能有效地求解一切整数规划。
整数规划的分类
- 变量全限制为整数时,称(完全)整数规划
- 变量部分限制为整数时,称混合整数规划
什么是分枝定界法
? 原理如下:
? 设有最大化的整数规划问题A,与它相应的线性规划为问题B,从解问题B开始,若其最优解不符合A的整数条件,那么B的最优目标函数必是A的最优目标函数(z^*)的上界(overline{z});而A的任意可行解的目标函数值将是 (z^*)的一个下界(underline z) ,分枝定界法就是将B的可行域分成子区域的方法。逐步减小(overline z)和增大(underline z)最终求到(z^*)
? 本质就是个二分回溯,逼近最大值的算法。Matlab算法如下:(强烈警告,(不会验证)由于比较懒,并未对算法正确性验证,思路上验证了一下没问题就码上来了,如果有错,请一定联系~~)
% c,A,Aeq,Beq,LB,UB,是linprog函数的相关参数,知道了它们就可以求出对应的线性规划最优解,
% now是目前已经知道的整数解的最大值
function y = control(c,A,Aeq,Beq,LB,UB,now)
ret = 0;
[x,fval] = linprog(c,A,Aeq,Beq,LB,UB); % x是最优解的解向量,fval是对应的函数值
if fval < now
y = fval;
return;
end % 如果得到的当前最优解fval小于已知的now,那说明最优整数解不在这个区间,则剪枝返回。
for i = 1 : length(x)
if rem(x(i),1) ~= 0 % rem(x,1)如果返回值不为0,则表示是小数。遍历x,找到第一个小数xi.
NUB = UB;
NLB = LB;
NUB(i) = floor(x(i)); % 把xi对应的上界更新为xi的向下取整。
NLB(i) = ceil(x(i)); % 把xi对应的下届更新为xi的向上取整。
fval1 = control(c,A,Aeq,Beq,LB,NUB,now); %分成了两个区间, 原来下界~向下取整
now = max(fval1,now);
fval2 = control(c,A,Aeq,Beq,NLB,UB,now); % 向上取整~原来上届
ret = max(ret,fval1); % 更新得到整数最优解,并退出。
ret = max(ret,fval2);
break
end
if i == length(x) %如果每个xi都是整数,那说明当前已经是整数最优,用j记录一下
j = length(x)+1;
end
end
if j == length(x)+1 %如果当前已经是整数最优,返回fval,否则返回ret。
y = fval;
else
y = ret;
end
end
非线性整数规划--蒙特卡洛算法(随机取样法)
什么是非线性规划?
? 就是自变量不再是线性的规划。没错就是这个。
蒙特卡洛算法
? 对于非线 性整数规划目前尚未有一种成熟而准确的求解方法,那么找到一个相对满意的解就成了主要需求。
? 蒙特卡洛算法是一种大量随机取样枚举解,以达到存在一种解,其函数值落在了我们期望的高值区(不要问我什么是高值区)。
? 那么具体多少次枚举合适呢?这是相对于问题而言的,举个例子:
? (0leq x_i leq 99 ,1 leq i leq 5, y = x_1^2 + x_2^2+3x_3^2+4x_4^2+2x_5^2-8x_1-2x_2-3x_3-x_4-2x_5) ,
? 解空间大小为(100^5 = 10^{10}),太大了,枚举不了
? 如果选择随机采样1e6,假设最优点不是孤立的奇点,并设目标函数落在可以接受的高值区的概率是0.00001,那么存在一个点落在高值区的概率为 1-(0.99999^{1000000}) (approx) 0.999954602,显然这个概率是可以接受的,也即是我们认为通过随机采样1e6,是能够得到满足期望的解。
? 随机采样的算法就不写了,因为太懒了(因为不会)。
今日感触:matlab的库函数是真的多,基础语法还是不行啊,以及数模的算法还挺有意思的,虽然高大上,其实也就那样。
以上是关于C# 分支定界法 01背包问题的主要内容,如果未能解决你的问题,请参考以下文章