Avatar billede thb Nybegynder
24. juli 2009 - 02:36 Der er 17 kommentarer

lave kombinationer

Jeg leger med noget genetik, men kan ikke helt hitte ud af hvordan jeg ud fra en liste med gener for generet alle kombinationer.

Det skal være dynamisk så det virker altid.

Jeg har en værdi der siger hvor mange kombinationer det skal ende med, og så har jeg et array med hoved elementerne:

$amount = 16;
$list = array(1, 2, 3, 4);

jeg skal ende med følgende:

1
2
3
4
1-2
1-3
1-4
2-3
2-4
3-4
1-2-3
2-3-4
3-4-1
4-1-2
1-2-3-4

her er kun 15 kombinationer, men den sidste er bare et 0.

jeg havde tænkt på noget med at loop en gang igennem med antallet af hoved elementer, fordi at der ligesom er det antal typer af kombinationer, men er gået lidt i stå.

Håber nogle kan hjælpe...

Thomas
Avatar billede arne_v Ekspert
24. juli 2009 - 04:27 #1
Et forslag:

<?php
function process($res) {
    echo implode('-', $res) . "\r\n";
}

function combrec($list, $n, $res) {
    if(count($res) < $n) {
        for($i = 0; $i < count($list); $i++) {
            $newlist = array_slice($list, $i + 1);
            $newres = array_merge($res, array($list[$i]));
            combrec($newlist, $n, $newres);
        }
    } else {
        process($res);
    }
}

function combfix($list, $n) {
    combrec($list, $n, array());
}

function comb($list) {
    for($i = 1; $i <= count($list); $i++) {
        combfix($list, $i);
    }
}

$list = array(1, 2, 3, 4);
comb($list);
?>
Avatar billede thb Nybegynder
24. juli 2009 - 05:25 #2
Det kan godt være at det bare er tidspunktet af døgnet, men jeg kan ikke passe din kode ind i det jeg havde i forvejen.

Sådan ser min funktion ud som lave listen:

function punnetFields ($morphs) {
   
    $str                 = '';
    $last                 = '';
    $lc                    = 0;
    $prefix                = $this->punnetPrefix($morphs);
   
    if (count($morphs) > 0) {
   
        sort($morphs);
       
        for ($x = 0; $x < count($morphs); $x++) {
           
            for ($i = 0; $i < count($morphs); $i++) {

                if ($x == 0) {
                   
                    // MAKING LIST WITH SINGLE NAMES
                    if ($morphs[$i]["super"] == 0 && ($morphs[$i]["gene"] != "res" || $morphs[$i]["het"] == 1)) {
                        if ($str != "") $str .= ',';
                        $str .= $prefix . $morphs[$i]["name"];
                    }
                   
                }
                elseif ($x == (count($morphs)-1)) {
                   
                    // MAKEING LIST OF ALL MORPHS TOGETHER
                    if ($morphs[$i]["super"] == 0 && ($morphs[$i]["gene"] != "res" || $morphs[$i]["het"] == 1)) {
                        if ($last != "") $last .= "|";
                        $last .= $prefix . $morphs[$i]["name"];
                        $lc++;
                    }
                   
                }
                else {
           
                    // REST OF CALCULATION
                           
                }
           
            }
           
           
            if ($x == (count($morphs)-1)) {
                if ($lc > 1) {
                    if ($str != "") $str .= ',';
                    $str .= $last;
                }
            }
           
        }
   
        $array = explode(",", "," . $str);
        $array[0] = (trim($prefix) != "") ? $prefix : 'Normal';
       
    }
    else  {
        $array = array("Normal");
    }
   
    return $array;
   
}

Udregningen skal laves der hvor // REST OF CALCULATION står.

Tror jeg skal gå i seng :)

Thomas
Avatar billede arne_v Ekspert
24. juli 2009 - 05:36 #3
$list = array(1, 2, 3, 4);

var det eksempel du selv gav i spørgsmålet.

Jeg kan ikke gennemskue din kode, men har du et array kan du kalde comb med det.

process skal tilrettes til dit behov.
Avatar billede _skou_ Nybegynder
24. juli 2009 - 11:59 #4
Endnu et forslag:

function combine($input) {
  $retArray = $input;
  while (!empty($input)) {
    $element = array_shift($input);
    $combined = combine($input);
    for ($i = 0; $i < count($combined); $i++) {
      $retArray[] = $element."-".$combined[$i];
    }
  }

  return $retArray;
}

print_r(combine(array(1, 2, 3, 4)));
print_r(combine(array(1, 2, 3, 4, 5)));
Avatar billede j4k0b Nybegynder
24. juli 2009 - 14:34 #5
offtopic: jeg tror arne_v er en bot nogen har udviklet til at sidde herinde og besvare spørgsmål, så bekymre dig ikke om tidspunktet på døgnet :-)
Avatar billede thb Nybegynder
24. juli 2009 - 14:39 #6
hehe... jeg den har jeg hørt før, men det var nu også mest i forhold til mit eget hovede at jeg tænkte på klokken.
Avatar billede arne_v Ekspert
25. juli 2009 - 02:24 #7
Nu er jeg i en tidszone som er 6 timer bagefter Danmark, så 04:27:15 er 22:27:15 !
Avatar billede thb Nybegynder
25. juli 2009 - 02:47 #8
hehe ;)

Jeg må dog undskylde at jeg ikke helt kan få nogen af jeres eksempler til at passe med min kode...

mit array ser således ud :

$morphs_array[] = array(
    "id" => $row->id,
    "name" => (($hets == 1) ? 'Het ' : '') . $row->name,
    "url" => $row->url,
    "gene" => $gene,
    "super" => $row->super,
    "superof" => $superof,
    "het" => $hets,
);   

og sådan her min kode så ud:

for ($x = 0; $x < count($morphs); $x++) {

if ($x == 0) {
   
// MAKING LIST WITH SINGLE NAMES
for ($i = 0; $i < count($morphs); $i++) {
    if ($morphs[$i]["super"] == 0 && ($morphs[$i]["gene"] != "res" || $morphs[$i]["het"] == 1)) {
        if ($str != "") $str .= ',';
        $str .= $prefix . $morphs[$i]["name"];
    }
}

}
elseif ($x == (count($morphs)-1)) {

// MAKEING LIST OF ALL MORPHS TOGETHER
for ($i = 0; $i < count($morphs); $i++) {
    if ($morphs[$i]["super"] == 0 && ($morphs[$i]["gene"] != "res" || $morphs[$i]["het"] == 1)) {
        if ($last != "") $last .= "|";
        $last .= $prefix . $morphs[$i]["name"];
        $lc++;
    }
}

if ($lc > 1) {
    if ($str != "") $str .= ',';
    $str .= $last;
}

}
else {

// HER MANGLER NOGET KODE

}

}

Jeg starter med at loop arrayet igennem og har så lavet første og sidste trin i 2 if sætninger, if ($x == 0) og if ($x == (count($morphs)-1)) så det skulle være på plads.

Det der mangler er så noget kode som sætter x antal sæt kombinationer op. Og de skulle gerne komme i rækkefølge:

a
b
c
d
a-b
a-c
a-d
b-c
b-d
c-d
a-b-c
b-c-d
a-c-d
a-b-d
a-b-c-d

Håber det var en bedre forklaring af min kode... :|

På forhånd tak...

Thomas
Avatar billede arne_v Ekspert
26. juli 2009 - 03:42 #9
Jeg er stadig lige forvirret hvad den kode gør og hvordan den relaterer sig til dit spørgsmål.
Avatar billede thb Nybegynder
26. juli 2009 - 07:35 #10
Mit array $morphs er min liste med 1,2,3,4.

Og tænkte at hvis der er 4 tal i $morphs så skal jeg bruge 4 blokke:

a
b
c
d


a-b
a-c
a-d
b-c
b-d
c-d


a-b-c
b-c-d
a-c-d
a-b-d


a-b-c-d

Derfor ville jeg loope igennem 4 gange...
Første gang ved jeg at den bare skal udskrive den enkelte morph, og sidste gang ved jeg at den skal sætte alle sammen sammen.

Men de x antal blokke der er imellem er forskellige alt efter hvor mange elementer der er i $morphs.

Thomas
Avatar billede _skou_ Nybegynder
26. juli 2009 - 10:17 #11
Hvorfor bruger du ikke bare de funktioner som vi har forslået?

Den funktion jeg har forslået. Returnere et array som indeholder de kombinationer du efterspørger...
Hvis de skal være i en bestemt rækkefølgende kan du bruge PHP's usort funktion.
Avatar billede thb Nybegynder
26. juli 2009 - 21:12 #12
Det har jeg skam også forsøgt.

Men jeg kunne ikke få dne til at retunere noget brugbart.
Jeg går ud fra at det er mig der klumper i den og derfor viser jeg min kode og spørger om hjælp til at indsætte det i mine kode.

Thomas
Avatar billede _skou_ Nybegynder
26. juli 2009 - 23:33 #13
Så vidt jeg kan se har du selv prøvet at lave en løsning, men mangler havldelen. Det vi har forslået er en komplet løsning...

Har du prøvet at teste vores forslag?

Jeg kan ikke se hvorfor de ikke skulle virke...
Hvis $morphs er et array som indeholder (1, 2, 3, 4) så returnere den funktion combine jeg har forslået i #4 et array indeholdende:
combine($morphs) => array(1, 2, 3, 4, 1-2, 1-3, 1-4, 1-2-3, 1-2-4, 1-2-3-4, 1-3-4, 2-3, 2-4, 2-3-4, 3-4)
Giver det dig ikke alt hvad du har brug for?
Avatar billede thb Nybegynder
27. juli 2009 - 11:39 #14
Jo det er rigtigt nok...

Men det gør bare at jeg skal lave om på mange af mine andre funktioner.

Det var derfor at jeg bedte om at få lave det i min kode, men eller må jeg jo sidde og lave alt mit om.

Thomas
Avatar billede thb Nybegynder
27. juli 2009 - 23:26 #15
Nå nu er jeg kommet videre og har brugt den ene af jeres forslag.
Synes dog at I begge skal smide et svar, så I kan dele point'ne, da begge løsninger virkede og jeg bare lige den der lige faldt mig ind.

Thomas
Avatar billede arne_v Ekspert
28. juli 2009 - 00:13 #16
ok
Avatar billede arne_v Ekspert
22. august 2009 - 17:09 #17
skou?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester