Scala 基于目标和计数的列表中值的多个组合

Scala 基于目标和计数的列表中值的多个组合,scala,list,recursion,collections,combinations,Scala,List,Recursion,Collections,Combinations,这是我的输入,为所有资源预设了目标,为每个资源预设了值,以及一个初始组合的列表(res,res的大小可以是任何值)。因此,最终结果应该是实现目标的多种资源组合,但值的总和不应超过目标,而应最接近目标(如res1,res2…resN等所示) 我试过这样做,但只得到一个组合,请任何人帮助解决这个问题 var tar: Double = target val listBuffer = ListBuffer[Container]() def doRecursion(r: String, v

这是我的输入,为所有资源预设了
目标
,为每个资源预设了
,以及一个初始组合的列表(
res
,res的大小可以是任何值)。因此,最终结果应该是实现目标的多种资源组合,但值的总和不应超过目标,而应最接近目标(如
res1
res2
…resN等所示)

我试过这样做,但只得到一个组合,请任何人帮助解决这个问题

var tar: Double = target
  val listBuffer = ListBuffer[Container]()

    def doRecursion(r: String, value: Double, count: Int = 1): List[Container] = {

      if (value < tar) {
        tar = tar - value
        listBuffer += Container(r, count, value / count)
        listBuffer.toList
      } else {
        if (listBuffer.toList.nonEmpty) {

            val last = listBuffer.toList.last
            listBuffer -= last
            listBuffer += last.copy(count = last.count + 1, time = (last.time * last.count) / (last.count + 1))

            tar = target - (listBuffer.toList.map(_.time).sum)    
          doRecursion(r, value)
        }
        else {
          doRecursion(r, value / 2, count + 1)
        }
      }
    }
var tar:Double=target
val listBuffer=listBuffer[Container]()
def doRecursion(r:String,value:Double,count:Int=1):列表[Container]={
如果(值<焦油){
焦油=焦油值
listBuffer+=容器(r、计数、值/计数)
listBuffer.toList
}否则{
if(listBuffer.toList.nonEmpty){
val last=listBuffer.toList.last
listBuffer-=最后一个
listBuffer+=last.copy(count=last.count+1,time=(last.time*last.count)/(last.count+1))
tar=target-(listBuffer.toList.map(u.time.sum)
数据修正(r,值)
}
否则{
数据引用(r,值/2,计数+1)
}
}
}

如果这是与工作相关的,而不是家庭作业练习,那么您要做的实际上是约束编程。一个很好的例子是OscaR()


编辑:如果这是一个家庭作业练习,请阅读有关OscaR的文章,并做一些类似于OscaR如何构建和修剪树的事情,这样你就可能能够以这种方式创建答案。

如果这是与工作相关的,而不是家庭作业练习,那么实际上你要做的是约束编程。一个很好的例子是OscaR()


编辑:如果这是一个家庭作业练习,不管怎样,读一读关于奥斯卡的书,做一些类似于它如何构建和修剪树的事情,你可能就能够用这种方式创建你的答案。

这会更接近你想要做的吗

case class Container(name:String,count:Long,value:Double)
//val target = 742.0
val target = 500.0
val value = 250.0
val a = Container("Resource1", 1 , 250.0)
val b = Container("Resource2", 2 , 125.0)
val c = Container("Resource3", 3 , 83.33)
val d = Container("Resource4", 1 , 250.0)

val cList1 = List(a,b,c,d)

val a1 = Container("Resource1", 2 , 125.0)
val b2 = Container("Resource2", 1 , 250.0)
val c3 = Container("Resource3", 3 , 83.33)
val d4 = Container("Resource4", 1 , 250.0)

val cList2 = List(a1,b2,c3,d4)

val a5 = Container("Resource1", 2 , 125.0)
val b6 = Container("Resource2", 1 , 250.0)
val c7 = Container("Resource3", 1 , 250.0)
val d8 = Container("Resource4", 3 , 83.33)

val cList3 = List(a5,b6,c7,d8)

@tailrec
def doRecursion(containerList: List[Container]): List[Container] = {
  if(containerList.map(_.value).sum <= target) containerList
  else doRecursion(containerList.map( c => Container(c.name, c.count + 1, c.value/2)))
}
doRecursion(cList1)
doRecursion(cList2)
doRecursion(cList3)

我已经注释掉/减少了
target
的旧值,因为
doRecursion()
只是返回原始列表。

这会更接近您想要做的吗

case class Container(name:String,count:Long,value:Double)
//val target = 742.0
val target = 500.0
val value = 250.0
val a = Container("Resource1", 1 , 250.0)
val b = Container("Resource2", 2 , 125.0)
val c = Container("Resource3", 3 , 83.33)
val d = Container("Resource4", 1 , 250.0)

val cList1 = List(a,b,c,d)

val a1 = Container("Resource1", 2 , 125.0)
val b2 = Container("Resource2", 1 , 250.0)
val c3 = Container("Resource3", 3 , 83.33)
val d4 = Container("Resource4", 1 , 250.0)

val cList2 = List(a1,b2,c3,d4)

val a5 = Container("Resource1", 2 , 125.0)
val b6 = Container("Resource2", 1 , 250.0)
val c7 = Container("Resource3", 1 , 250.0)
val d8 = Container("Resource4", 3 , 83.33)

val cList3 = List(a5,b6,c7,d8)

@tailrec
def doRecursion(containerList: List[Container]): List[Container] = {
  if(containerList.map(_.value).sum <= target) containerList
  else doRecursion(containerList.map( c => Container(c.name, c.count + 1, c.value/2)))
}
doRecursion(cList1)
doRecursion(cList2)
doRecursion(cList3)

我已注释掉/减少了
target
的旧值,因为
doRecursion()
只是返回原始列表。

如果我理解正确,您希望获取容器列表,并确保列表中每个
容器的值之和不超过
target
的值?你必须将一个值除以2还是减去多余的值?@RobertUdah…正确,但如果超过,我需要增加计数并进行调整。如果我的答案解决了问题,你介意将其标记为已接受的答案吗?如果我理解正确,您希望获取容器列表,并确保列表中每个
容器
的值之和不超过
目标
的值?你必须将一个值除以2还是减去多余的值?@RobertUdah…正确,但如果超过,我需要增加计数并进行调整。如果我的答案解决了问题,你介意将其标记为已接受的答案吗?这与我的工作有关,试着用评论来传达这些答案。如果你被冒犯了,我很抱歉,但我仍然认为我给了你一个有用的答案,因为你在做约束编程,奥斯卡是一个很好的开始。这是我的工作相关,试着用评论来表达这些答案。如果你被冒犯了,我很抱歉,但我仍然认为我给了你一个有用的答案,因为你正在做约束编程,奥斯卡是一个很好的开始库。
res0: List[Container] = List(Container(Resource1,2,125.0), Container(Resource2,3,62.5), Container(Resource3,4,41.665), Container(Resource4,2,125.0))
res1: List[Container] = List(Container(Resource1,3,62.5), Container(Resource2,2,125.0), Container(Resource3,4,41.665), Container(Resource4,2,125.0))
res2: List[Container] = List(Container(Resource1,3,62.5), Container(Resource2,2,125.0), Container(Resource3,2,125.0), Container(Resource4,4,41.665))