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

时间:2016-05-16 07:10:22

标签: scala list recursion collections combinations

这是我输入的所有资源预设为target,每个资源为value,一个初始组合的列表(resres的大小可能是任何内容)。因此最终结果应该是实现目标的多种资源组合,但值的总和不应超过目标,但应该最接近目标(显示在res1res2 .. ..等等)

case class Container(name:String,count:Long,value:Double)

val target = 742.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 res = 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 res1 = 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 res2 = List(a5,b6,c7,d8)

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

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

2 个答案:

答案 0 :(得分:1)

这会更接近您尝试做的事情吗?

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)

我得到了结果:

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))

我已评论/减少target的旧值,因为doRecursion()只返回原始列表。

答案 1 :(得分:-1)

如果这是与工作相关的,而不是家庭作业,那么你要做的就是实际的约束编程。一个好用的是OscaR(https://www.info.ucl.ac.be/~pschaus/cp4impatient/firststeps.html)。

编辑:如果是家庭作业,无论如何都要阅读有关OscaR的内容,并做一些类似于构建和修剪树木的内容,您可能会以这种方式创建答案。