Many combinations of values ​​in a list based on target and quantity

This is my input with a preset of target for all resources and value for each resource, and a list of one source combination ( res , res size can be anything). Thus, the end result should be several combinations of resources to achieve the goal, but the sum of the values ​​should not exceed the goal, but should be closer to the goal (shown in res1 , res2 .... resN, etc.)

 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) 

I tried so, but I get only one combination, please help us in solving this issue.

 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) } } } 
+5
source share
2 answers

Will it be closer to what you are trying to do?

 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) 

And I get the result:

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

I commented / reduced the old value for target since doRecursion() just returns the original list.

+1
source

If this is related to work, not homework, what you are trying to do is actually a programming limitation. Good to use is OscaR ( https://www.info.ucl.ac.be/~pschaus/cp4impatient/firststeps.html ).

EDIT: if it's homework, read about OscaR anyway and do something similar to how it builds and prunes its trees, and you can probably create your answer this way.

-1
source

All Articles