2016-05-16 39 views
5

To jest moje wejście z ustawieniem wstępnym target dla wszystkich zasobów i value dla każdego zasobu, a lista jednej początkowej kombinacji (res, rozmiar res może być dowolna). Tak więc końcowym wynikiem powinny być wielokrotne kombinacje zasobów, aby osiągnąć cel, ale suma wartości nie powinna przekraczać celu, ale powinna być najbliżej celu (pokazana w res1, res2 .... resN itp.)Wiele kombinacji wartości na liście w oparciu o cel i liczba

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) 

Próbowałem tak, ale otrzymałem tylko jedną kombinację, proszę, pomóżcie w rozwiązaniu tego problemu.

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

Jeśli dobrze rozumiem, chcesz wziąć listę kontenerów i upewnić się, że suma wartości każdego 'Container' na liście nie przekracza wartości' target'? Czy musisz podzielić wartość przez 2 lub po prostu odjąć nadmiar? –

+0

@RobertUdah .... poprawny, ale jeśli to przekracza, muszę zwiększyć liczbę i dostosować. – Jet

+0

Jeśli moja odpowiedź rozwiąże problem, czy myślisz o zaznaczeniu go jako zaakceptowanej odpowiedzi? –

Odpowiedz

-1

Jeśli chodzi o pracę, a nie o pracę domową, to, co próbujesz zrobić, to programowanie z ograniczeniami. Dobrym rozwiązaniem jest OscaR (https://www.info.ucl.ac.be/~pschaus/cp4impatient/firststeps.html).

EDYCJA: Jeśli jest to zadanie domowe, przeczytaj o OscaR i czyń coś podobnego do tego, jak buduje i przycina swoje drzewa i prawdopodobnie będziesz w stanie stworzyć odpowiedź w ten sposób.

+0

To jest moja praca związana, spróbuj użyć komentarzy do przekazania tego rodzaju odpowiedzi. – Jet

+0

Przykro mi, jeśli poczułeś się urażony, ale nadal uważam, że dałem ci użyteczną odpowiedź, ponieważ robisz programowanie więzów i że OscaR jest dobrą biblioteką na początek. – critium

1

Czy byłby bliżej tego, co próbujesz zrobić?

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) 

I uzyskać wynik:

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

miałem wykomentowane/zmniejszoną starą wartość dla target jak doRecursion() prostu przywraca pierwotną listę.