Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 基于不同促销方式的总价最小化算法_Algorithm_Kotlin - Fatal编程技术网

Algorithm 基于不同促销方式的总价最小化算法

Algorithm 基于不同促销方式的总价最小化算法,algorithm,kotlin,Algorithm,Kotlin,我不知道使用什么标题,但我的问题如下: 我有X种产品要买——每一种都有一定的价格。 我还提供了4种类型的促销活动: twoItemPromotion->可用于2件物品,最便宜的一件的折扣为22% threeItemPromotion->可用于3个项目,最便宜的一个项目的折扣为44% fourItemPromotion->可用于4个项目,最便宜的一个项目的折扣为66% fiveOrMoreItemPromotion->可用于5个或更多项目,最便宜的一个项目的折扣为99.9% 我可以按照我的意愿

我不知道使用什么标题,但我的问题如下: 我有X种产品要买——每一种都有一定的价格。 我还提供了4种类型的促销活动:

  • twoItemPromotion->可用于2件物品,最便宜的一件的折扣为22%
  • threeItemPromotion->可用于3个项目,最便宜的一个项目的折扣为44%
  • fourItemPromotion->可用于4个项目,最便宜的一个项目的折扣为66%
  • fiveOrMoreItemPromotion->可用于5个或更多项目,最便宜的一个项目的折扣为99.9%
我可以按照我的意愿分割X个项目的订单,例如,如果我想购买10个项目,那么我可以将其分割为5个使用twoItemPromotion的订单。或者2个订单有3个项目促销,1个订单有5个或更多项目促销

在这里,我对一些价值对象进行建模,以表示商品和促销:

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}
]