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个物件。
查看全文
相关阅读:
vue-cli router的使用
vue element new vue const
mac terminal update management pack
关于MAC升级后,vim更新插件报错
flex入门----基础知识
常用的flex知识 ,比起float position 好用不少
npm 安装nodesass 或者包含nodesass的脚手架工具报错问题
anglar cli的 rxjs_1.of is not a function
npm node sass 安装报错
axios ajax fetch 区别
原文地址:https://www.cnblogs.com/xiaotaoliang/p/354758.html
最新文章
HDU-2255 奔小康赚大钱
【普通の随笔】3.26
BZOJ-1007 水平可见直线
BZOJ-1003 物流运输trans
BZOJ-1001 狼抓兔子
SRM477
SRM476
SRM475
SRM474
SRM473
热门文章
SRM472
SRM471
2-Sat小结
SRM470
SRM469
如何删除linux是用root生成的文件夹以及文件
Vuejs methods how to use
background-size css background-images
vue-cli background iamge
css hover dropdown
Copyright © 2011-2022 走看看