zoukankan
html css js c++ java
背包算法,C#
穷举法,这个最好理解了,省得死那么多脑细胞
/**/
///
<summary>
///
KnapSack
背包问题。
///
</summary>
public
class
KnapSack
{
/**/
///
<summary>
///
可放入背包的物件
///
</summary>
public
interface
PackItem
{
/**/
///
<summary>
///
可比对的值,统一转为decimal
///
</summary>
decimal
Value
{
get
; }
}
/**/
///
<summary>
///
用来做位屏蔽的数组
///
</summary>
private
int
[] mask
=
null
;
public
KnapSack()
{
}
/**/
///
<summary>
///
穷举
///
</summary>
///
<param name="array">
PackItem对象数组
</param>
///
<param name="upperLimit">
比对上限
</param>
///
<param name="resultSum">
最后的总和结果
</param>
///
<returns>
被挑选对象的数组
</returns>
public
PackItem[] EndList(PackItem[] array,
decimal
upperLimit,
ref
decimal
resultSum)
{
initMask(array.Length);
//
初始化屏蔽数组
int
spaceNum
=
GetSpaceNum(array.Length);
//
穷举数
int
plan
=
0
;
//
选择的方案号
decimal
max
=
0
;
//
能达到的最大值
decimal
sum
=
0
;
//
阶段性统计数
for
(
int
i
=
1
;i
<=
spaceNum;i
++
)
//
穷举第 i 种情况
{
sum
=
0
;
//
开始一种新情况,阶段性统计数归零
for
(
int
j
=
0
; j
<
array.Length; j
++
)
//
处理每个物件
{
if
((i
&
mask[j])
==
mask[j])
//
在本方案(i)中,第 j 个物件是否要选择
{
sum
+=
array[j].Value;
//
选择第j个物件,价值加到阶段性统计数上
}
}
if
( sum
>
max
&&
sum
<=
upperLimit)
//
是否满足条件?
{
max
=
sum;
//
满足条件,设定最新的最大值
plan
=
i;
//
记录下来这是第几个方案
}
}
resultSum
=
max;
//
结果
IList result
=
new
ArrayList();
//
把选中的方案的物件挑出来
for
(
int
i
=
0
;i
<
array.Length;i
++
)
{
if
((plan
&
mask[i])
==
mask[i])
//
第i个物件是否选中了。
{
result.Add(array[i]);
//
选中了,加入到结果列表
}
}
PackItem[] resultArray
=
new
PackItem[result.Count];
//
放到数组里面
result.CopyTo(resultArray,
0
);
return
resultArray;
//
返回
}
/**/
///
<summary>
///
初始化 mask
///
</summary>
///
<param name="arrayLen"></param>
private
void
initMask(
int
arrayLen)
{
mask
=
new
int
[arrayLen];
for
(
int
i
=
0
;i
<
arrayLen;i
++
)
{
mask[i]
=
(
1
<<
i);
//
左移
}
}
/**/
///
<summary>
///
取得组合总数,高中数学忘记了吧,复习吧
///
</summary>
///
<param name="upper"></param>
///
<returns></returns>
private
int
GetSpaceNum(
int
upper)
{
int
nUpper
=
GetSeq(upper);
//
n!
int
c
=
0
;
for
(
int
i
=
1
; i
<=
upper; i
++
)
//
C(n,r) + C(n,r-1) +
+ C(n,1)
{
int
rs
=
GetSeq(i);
int
n2
=
GetSeq(upper
-
i);
if(n2 == 0)
c++;
else
c
+=
nUpper
/
(rs
*
n2);
//
C(n,r) = n! / ( (n-i)! * i! )
}
return
c;
}
/**/
///
<summary>
///
阶乘的递归算法
///
</summary>
///
<param name="n"></param>
///
<returns></returns>
private
int
GetSeq(
int
n)
{
if
(n
>
1
)
return
n
*
GetSeq(n
-
1
);
return
1
;
}
测试
#region
测试
public
class
TestPackObject : BackPack.PackItem
{
int
v;
public
TestPackObject(
int
v)
{
this
.v
=
v;
}
/**/
///
<summary>
///
可比对的值,统一转为decimal
///
</summary>
public
decimal
Value
{
get
{
return
v; }
set
{ v
=
(
int
) value; }
}
}
public
static
void
test()
{
TestPackObject[] array
=
new
TestPackObject[
5
];
//
{ 1,4,3,6,10 };
array[
0
]
=
new
TestPackObject(
1
);
array[
1
]
=
new
TestPackObject(
4
);
array[
2
]
=
new
TestPackObject(
3
);
array[
3
]
=
new
TestPackObject(
6
);
array[
4
]
=
new
TestPackObject(
10
);
KnapSack ks
=
new
KnapSack();
decimal
sum
=
0
;
KnapSack.PackItem[] result
=
ks.EndList(array,
12
,
ref
sum);
Console.WriteLine(
"
sum=
"
+
sum);
foreach
(KnapSack.PackItem item
in
result)
{
Console.WriteLine(
"
object.value=
"
+
item.Value);
}
}
#endregion
这个算法最多不能超过32个物件。
查看全文
相关阅读:
Word 转换为 PDf 的技术方案
[转载]sql server 常用存储过程
Redmine 初体验
Quartz.net Tutorial Lesson 1
[转载]sql server TSQL 区分字符串大小写 的两种方法
[原创]sql server inner join 效率测试
java实现树的一般操作
【转】Mybatis中进行批量更新
【转载】单例模式的7种写法(整合自两篇文章)
mybtis批量insert传入参数为list
原文地址:https://www.cnblogs.com/xiaotaoliang/p/354758.html
最新文章
SpringBoot系列:Spring Boot使用模板引擎FreeMarker
SQL 用本表字段更新本表【整理】
Asp.net 根据IP地址获取跨网段mac地址函数【搜藏】
SQL 错误14010 的处理方法【搜藏】
delphi 对应 c# 的一些函数及类型的转换方法【原】
c# WebService返回结构复杂的ArrayList 的转化问题【原】
c# 避开淘宝助理检测上传宝贝描述含其他店铺图片的小工具【原】
使用串口复用工具让多个程序共享一个串口数据【整理】
SQL函数 将一个字段分隔成一个表的函数【搜藏】
C# 简单软件有效期注册的实现【原】
热门文章
JavaWeb基础之JdbcUtils工具类1.0
mysql数据库问题———登录进去无法操作显示You must reset your password using ALTER USER statement before executing this statement
oracle跟SQL Server 2005 的区别
spring框架对于实体类复杂属性注入xml文件的配置
SSM框架之AOP、动态代理、事务处理相关随笔
SSM框架中测试单元的使用,spring整合Junit
为sql server客户端连接添加别名
jqgrid 属性说明
teamlab与redmine试用对比报告
Redmine集成LDAP认证
Copyright © 2011-2022 走看看