Algorithm 基于不同促销方式的总价最小化算法
我不知道使用什么标题,但我的问题如下: 我有X种产品要买——每一种都有一定的价格。 我还提供了4种类型的促销活动:Algorithm 基于不同促销方式的总价最小化算法,algorithm,kotlin,Algorithm,Kotlin,我不知道使用什么标题,但我的问题如下: 我有X种产品要买——每一种都有一定的价格。 我还提供了4种类型的促销活动: twoItemPromotion->可用于2件物品,最便宜的一件的折扣为22% threeItemPromotion->可用于3个项目,最便宜的一个项目的折扣为44% fourItemPromotion->可用于4个项目,最便宜的一个项目的折扣为66% fiveOrMoreItemPromotion->可用于5个或更多项目,最便宜的一个项目的折扣为99.9% 我可以按照我的意愿
- twoItemPromotion->可用于2件物品,最便宜的一件的折扣为22%
- threeItemPromotion->可用于3个项目,最便宜的一个项目的折扣为44%
- fourItemPromotion->可用于4个项目,最便宜的一个项目的折扣为66%
- fiveOrMoreItemPromotion->可用于5个或更多项目,最便宜的一个项目的折扣为99.9%
fun main() {
val itemA = Item(name = "A", price = 1000)
val itemB = Item(name = "B", price = 1500)
val itemC = Item(name = "C", price = 2000)
val itemD = Item(name = "D", price = 1200)
val itemE = Item(name = "E", price = 1600)
val itemF = Item(name = "F", price = 1300)
val itemG = Item(name = "G", price = 2400)
val itemH = Item(name = "H", price = 800)
val itemJ = Item(name = "J", price = 1400)
val itemK = Item(name = "K", price = 1200)
val itemListToBuy = listOf(itemA, itemB, itemC, itemD, itemE, itemF, itemG, itemH, itemJ, itemK)
val twoItemPromotion = Promotion(numberOfItems = 2, discountForCheapest = 0.22)
val threeItemPromotion = Promotion(numberOfItems = 3, discountForCheapest = 0.44)
val fourItemPromotion = Promotion(numberOfItems = 4, discountForCheapest = 0.66)
val fiveOrMoreItemPromotion = Promotion(numberOfItems = 5, discountForCheapest = 0.9999)
}
data class Item(val name: String, val price: Int)
data class Promotion(val numberOfItems: Int, val discountForCheapest: Double)
您将如何着手检索哪些产品的最佳组合以用于哪些促销活动,以及可以节省多少费用?我很好奇,如果我想用它来计算500件左右的物品,计算最佳成分的有效方法是什么
编辑:
要澄清促销活动的运作方式:
如果我订购这3个项目:
val itemA = Item(name = "A", price = 1000)
val itemB = Item(name = "B", price = 1500)
val itemC = Item(name = "C", price = 2000)
如果没有促销,它将花费1000+1500+2000=4500
。
但是,当考虑到三项促销时,最便宜的一项是一项促销,其价格降低了44%=>itemA成本:1000*(1-0.44)=556
和其他项目-项目B和项目C-具有未受影响的价格,这意味着它们共同成本556(折扣最便宜的项目)+1500+2000=4056
编辑2:
现在我有这个:
fun main() {
val itemA = Item(name = "A", price = 1000)
val itemB = Item(name = "B", price = 1500)
val itemC = Item(name = "C", price = 2000)
val itemD = Item(name = "D", price = 1200)
val itemE = Item(name = "E", price = 1600)
val itemF = Item(name = "F", price = 1300)
val itemG = Item(name = "G", price = 2400)
val itemH = Item(name = "H", price = 800)
val itemJ = Item(name = "J", price = 1400)
val itemK = Item(name = "K", price = 1200)
val itemList = listOf(itemA, itemB, itemC, itemD, itemE, itemF, itemG, itemH, itemJ, itemK)
val sorted = itemList.sortedBy { it.price }
val bestResult = mutableListOf(Result(0.0, 0))
for (i in 0 until sorted.size) {
var best = Result(
cost = (sorted.get(i).price) + bestResult.get(i).cost,
groupSize = 1
)
for (s in 2..5) {
val candidate = Result(cost = getPrice(i - s, sorted), groupSize = s)
if (candidate.cost < best.cost) {
best = candidate
}
}
bestResult.add(best)
}
bestResult.forEach { println(it) }
}
fun getPrice(numberOfItems: Int, list: List<Item>): Double {
val found = mutableListOf<Int?>()
for(i in 0 until numberOfItems) {
found.add(list.getOrNull(i)?.price)
}
val filterNotNull = found.filterNotNull()
return when(numberOfItems) {
2 -> (filterNotNull.get(0) * 0.78 + filterNotNull.get(1))
3 -> (filterNotNull.get(0) * 0.56 + filterNotNull.get(1) + filterNotNull.get(2))
4 -> (filterNotNull.get(0) * 0.34 + filterNotNull.get(1) + filterNotNull.get(2) + filterNotNull.get(3))
5 -> (1.0 + filterNotNull.get(1) + filterNotNull.get(2) + filterNotNull.get(3) + filterNotNull.get(4))
else -> 1000000000.0
}
}
data class Item(val name: String, val price: Int)
data class Result(val cost: Double, val groupSize: Int)
fun main(){
val itemA=项目(name=“A”,价格=1000)
val itemB=项目(name=“B”,价格=1500)
val itemC=Item(name=“C”,price=2000)
val itemD=项目(name=“D”,价格=1200)
val itemE=项目(name=“E”,价格=1600)
val itemF=项目(name=“F”,价格=1300)
val itemG=项目(name=“G”,价格=2400)
val itemH=项目(name=“H”,价格=800)
val itemJ=项目(name=“J”,价格=1400)
val itemK=项目(name=“K”,价格=1200)
val itemList=listOf(项目a、项目b、项目c、项目d、项目e、项目f、项目g、项目h、项目j、项目k)
val sorted=itemList.sortedBy{it.price}
val bestResult=mutableListOf(结果(0.0,0))
for(i在0中,直到排序.size){
var最佳=结果(
成本=(排序的.get(i).price)+最佳结果.get(i).cost,
groupSize=1
)
对于(2..5中的s){
val候选者=结果(成本=getPrice(i-s,排序),组大小=s)
if(候选成本<最佳成本){
最佳=候选人
}
}
最佳结果。添加(最佳)
}
bestResult.forEach{println(it)}
}
fun getPrice(numberOfItems:Int,list:list):双精度{
val found=mutableListOf()
for(i在0中,直到numberOfItems){
找到。添加(列表。获取完整(i)?价格)
}
val filterNotNull=找到。filterNotNull()
返回时间(numberOfItems){
2->(filterNotNull.get(0)*0.78+filterNotNull.get(1))
3->(filterNotNull.get(0)*0.56+filterNotNull.get(1)+filterNotNull.get(2))
4->(filterNotNull.get(0)*0.34+filterNotNull.get(1)+filterNotNull.get(2)+filterNotNull.get(3))
5->(1.0+filterNotNull.get(1)+filterNotNull.get(2)+filterNotNull.get(3)+filterNotNull.get(4))
其他->100000000.0
}
}
数据类项(val名称:字符串,val价格:Int)
数据类结果(val成本:双倍,val组大小:Int)
但是它没有正确地计算价格——我假设我在getPrice()方法中有错误。有没有办法解决这个问题?首先,你需要观察一下。把你的物品从最便宜的到最贵的分类 现在假设我有一个声称是最优的分组。看看有最便宜商品的那一组。如果组中的其他项目不是下一个最便宜的项目,我可以权衡哪些项目在组中,直到它是,而不会使它变得更糟。然后我可以对下一个做同样的事情 结果是,您可以找到一个最佳排列,其中每个组在该列表中是连续的。这一观察结果大大减少了你的可能性组合爆炸 现在它是动态规划的一个很好的候选者,如下所示
item_infos = ((i.price, i.name, i) for i in item_list_to_buy)
item_infos = sorted(item_infos)
best_result = [{cost: 0, group_size: 0}]
for i in range(len(item_infos)):
best = {cost: item_infos[i][0] + best_result[i].cost, group_size: 1}
for s in [2, 3, 4, 5]:
candidate = do calculation of group of size s ending here
if candidate.cost < best.cost:
best = candidate
best_result.append(best)
然后您的最佳结果将是(手动执行此操作的模错误)
现在我们读下来
我们希望最后5个作为一个组[J、B、E、C、G]
。这使我们在{cost:4700.8,group_size:5}
下一个最后5个作为一个组[H,a,K,D,F]
该算法以线性时间运行,因此为500个项目找到最佳答案应该很容易
注意:如果你的促销开始是一组特定的项目组合在一起,那么这个问题从简单到潜在的NP完全…我试图理解这个问题。你说的“最便宜的”是什么意思?比如说我买两个,第三个我可以少买22%的?还是别的什么?抱歉-我不明白。添加了“编辑”示例,说明其实际工作原理。好的,因此您正在查找500个项目,因为项目的定价不同,结果将随输入而变化,尽管500是固定的。您需要准确地指定A、B、C、。。。按顺序出现。要搜索的关键字是“动态规划”和“划分问题”。你需要考虑各种各样的选择;您可以使用一些代数限制来减少搜索树(严格控制),并让DP回溯确定最佳解决方案。这是一个技术应用的问题,而不是一个特定的算法
[
(800, 'H', itemH)
, (1000, 'A', itemA)
, (1200, 'D', itemD)
, (1200, 'K', itemK)
, (1300, 'F', itemF)
, (1400, 'J', itemJ)
, (1500, 'B', itemB)
, (1600, 'E', itemE)
, (2000, 'C', itemC)
, (2400, 'G', itemG)
]
[
{cost: 0, group_size: 0}
, {cost: 800, group_size: 1}
, {cost: 1980, group_size: 2}
, {cost: 2648, group_size: 3}
, {cost: 3760, group_size: 3}
, {cost: 4700.8, group_size: 5}
, {cost: 5901, group_size: 5}
, {cost: 7256, group_size: 4}
, {cost: 8449.2, group_size: 5}
, {cost: 10261.3, group_size: 5}
, {cost: 12202.2, group_size: 5}
]