[PHP] Pagina conta verghe per carpenteria

Discussione in 'PHP' iniziata da Felotti, 7 Ottobre 2019.

  1. Felotti

    Felotti Nuovo Utente

    Registrato:
    7 Ottobre 2019
    Messaggi:
    9
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    Buongiorno a tutti.
    Sto creando, tramite php, una sorta di "programma conta verghe (tubi)".
    Mi spiego meglio.
    In molte carpenterie sono presenti delle macchine laser che tagliano le verghe (ossia i tubi) in vari pezzi disegnati dagli uffici tecnici.
    Queste verghe hanno una lunghezza fissa di 5800 mm.
    Ora, mettiamo il caso che in ordine ci sono:
    5 pezzi di lunghezza 3000 mm
    5 pezzi di lunghezza 2000 mm
    5 pezzi di lunghezza 500 mm
    e 5 pezzi di lunghezza 300 mm
    Per ottimizzare la quantità di verghe da utilizzare, bisogna far si che in ogni verga ci sia il maggior numero di pezzi possibili.
    Per esempio:
    Verga 1: 1 pezzo da 3000 mm, 1 pezzo da 2000 mm, 1 pezzo da 500 mm e un pezzo da 300mm.
    Si procede così fino a quanto le quantità da produrre vengono termitate.
    Al giorno d'oggi questa gestione avviene manualmente, ma con l'avvento delle nuove tecnologie bisogna ottimizzarsi sotto ogni punto di vista.
    Ora, io mi sto cimentando in questa programmazione ma mi sorgono delle difficoltà (non utilizzando php e html da diverso tempo).
    Avevo in mente di chiedere all'utente il numero di articoli da dover tagliare (nell'esempio precedente 4 per intenderci), in modo da generare un array multidimensionale composto da 4 righe.
    Tramite il metodo POST (o anche GET dato che non sono dati sensibili), ricevere questa informazione dalla pagina html e generare questo array dove si richiedono anche:
    Dimensioni dei pezzi, quantità e codice articolo.
    Avendo un risultato del genere:
    $fabbisogni = array(
    "Codice" => array ();
    "Dimensione" => array ();
    "Quantità" => array ();
    );
    Dopodichè, tramite cicli for e while, ottimizzare l'utilizzo delle verghe e stampare a video il numero di verghe utilizzate ed il modo in cui vengono utilizzate, per ottenere un risultato simile:

    Numero verghe utilizzate: 5
    Verga 1: codice1 (3000 mm quantità 1), codice2 (2000mm quantità 1) ...... e così via.
    Verga 2: .....
    .....

    N.B: Se in una verga avanzano, per esempio, 200 mm, ma il pezzo più piccolo misura 300 mm, non posso utilizzare questi 200 mm e 100 mm di un'altra verga. La quantità rimasta sarebbe dunque da considerare "scarto".

    Mi sorgono delle difficoltà nella creazione dinamica di questi array e nei cicli.
    Qualcuno può darmi una mano? :(

    Grazie in anticipo
     
    Ultima modifica: 7 Ottobre 2019
  2. macus_adi

    macus_adi Utente Attivo

    Registrato:
    5 Dicembre 2017
    Messaggi:
    962
    Mi Piace Ricevuti:
    56
    Punteggio:
    28
    Sesso:
    Maschio
    Occupazione:
    Developer
    Località:
    L'Aquila
    Prova con questa, non è ottimizzata ma ti da una base:
    PHP:
    <?php
    /**
    * Created by phpS
    * User: macus_adi
    * Project Name: _CI_utilsLibs
    * File: Goptimeze.php
    * Path: Goptimeze
    * Date: 09/10/2019
    * Time: 10:49
    */

    class Goptimeze {

       public 
    $mLen=5800;

       public 
    $result=[];

       public 
    $html='';

       public function 
    __construct() {
          
    ini_set('memory_limit',-1);
       }
       public function 
    creaLen($data){
          
    $bs=[];
          foreach (
    $data as $k=>$v){
             (!isset(
    $bs[$v[1]]))?$bs[$v[1]]=$v[0]:$bs[$v[1]]+=$v[0];
          }
          
    krsort($bs);
          
    $data=[];
          foreach (
    $bs as $k=>$v){
             
    $data[]=[$v,$k];
          }
          foreach (
    $data as $items){
             
    $this->creaTravi($items);
          }
          
    $this->createOutput();
          return 
    $this;
       }
       public function 
    creaTravi($data){
          for(
    $i=0;$i<$data[0];$i++){
             if(
    $this->findInPath($data))$this->findLocation($data[1]);
          }
       }
       public function 
    findInPath($data){
          
    $num=$data[0];
          
    $el=0;
          foreach (
    $this->result as $k=>$v){
             foreach (
    $v['values'] as $items){
                if(
    $items==$data[1])$el++;
             }
          }
          if(
    $el>=$num)return false;
          else return 
    true;
       }
       public function 
    findLocation($len){
          if(empty(
    $this->result))$this->Trave($len);
          else{
             
    $loc=false;
             foreach (
    $this->result as $k=>$v){
                if(!
    $loc && $this->result[$k]['len']-$len>=0){
                   
    $this->result[$k]['values'][]=$len;
                   
    $this->result[$k]['len']-=$len;
                   
    $loc=true;
                }
             }
             if(!
    $loc)$this->Trave($len);
          }
       }
       public function 
    Trave($in){
          
    $this->result[]=['values'=>[$in],'len'=>$this->mLen-$in];
       }

       public function 
    createOutput(){
          
    $table='<table>
          <thead><tr><th>Taglio</th><th>Elementi</th><th>Sfreddo</th></tr></thead><tbody></tbody>'
    ;
          foreach (
    $this->result as $k=>$v){
             
    $table.='<tr><td>'.($k+1).'</td><td><ul>';
             foreach (
    $v['values'] as $items)$table.='<li>'.$items.'</li>';
             
    $table.='</ul></td><td>'.$v['len'].'</td></tr>';
          }
          
    $table.='</tbody></table>';
          return 
    $this->html=$table;
       }

    }
    Per richiamarla basta fare in questo modo, non so se funziona come credi o se ha qualche bug...

    PHP:
    $opt=new Goptimeze();
    $data=[
       [
    5,2000],
       [
    5,500],
       [
    5,300],
       [
    3,250],
       [
    15,575],
       [
    10,25],
       [
    4,1300],
       [
    5,3000],
    ];
    echo 
    $opt->creaLen($data)->html;
    Ho aggiunto qualche dato per elaborare il tutto e per vedere in che modo si comporta....

    Naturalmente manca, la gestione delle possibili varianti per limitare gli sfreddi (residuo) di ogni trave, ottimizzazione e calcolo del taglio
     
    A Felotti piace questo elemento.
  3. Felotti

    Felotti Nuovo Utente

    Registrato:
    7 Ottobre 2019
    Messaggi:
    9
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    Ciao Macus_adi
    Innanzitutto ti ringrazio molto per il tempo che mi hai dedicato.
    Appena rientro in ufficio testo il tutto.
    Sto ultimando il file html per la richiesta all'utente dei fabbisogni in modo da farlo interagire con il codice PHP che mi hai mandato.
    Ti do aggiornamenti il prima possibile
     
  4. macus_adi

    macus_adi Utente Attivo

    Registrato:
    5 Dicembre 2017
    Messaggi:
    962
    Mi Piace Ricevuti:
    56
    Punteggio:
    28
    Sesso:
    Maschio
    Occupazione:
    Developer
    Località:
    L'Aquila
    Modifica il metodo createOutput in questo modo!:
    PHP:

    public function createOutput(){
       
    $table='<table>
       <thead><tr><th>Taglio</th><th>Elementi</th><th>Numero Tagli</th><th>Sfreddo</th></tr></thead><tbody></tbody>'
    ;
       
    $all_t=0;
       
    $sf=0;
       foreach (
    $this->result as $k=>$v){
          
    $table.='<tr><td>'.($k+1).'</td><td><ul>';
          
    $all_t+=count($v['values']);
          foreach (
    $v['values'] as $items)$table.='<li>'.$items.'</li>';
          
    $table.='</ul></td><td>'.count($v['values']).'</td><td>'.$v['len'].'</td></tr>';
          
    $sf+=$v['len'];
       }
       
    $table.='</tbody>';
       
    $table.='<tfoot><tr><th>Barre: '.count($this->result).'</th>
       <th></th><th>Tagli : '
    .$all_t.'</th><th>Sfreddo : '.$sf.'</th></tr></tfoot>';
       
    $table.='</table>';
       return 
    $this->html=$table;
    }
     

    Files Allegati:

  5. Felotti

    Felotti Nuovo Utente

    Registrato:
    7 Ottobre 2019
    Messaggi:
    9
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    Ho provato a scrivere un codice alternativo (senza iterazione con il client) per "semplificare" il codice.
    Te lo allego di seguito, fammi sapere che ne pensi
    PHP:
        $lunghezze_pezzi = array ("3000""2000""500""800"); //array lunghezze pezzi
        
    $quantita = array ("5""5""5""5"); //array quantità
        
    $tubo_corrente = array (); //memorizzo in che modo vengono tagliato il tubo
        
    $risultato = array(); //array composto dai vari array dei tubi tagliati
        
    $sfridi = array (); //verifico gli sfridi di verga in verga
        
    $tubo 5800//lunghezza iniziale tubo
        
    $verghe_tagl 0//numero di verghe utilizzate

        
    for($i=0$i<count($lunghezze_pezzi); $i++){  //scorrimento array lunghezze
            
    for($j=0$j<count($quantita); $j++){  //scorrimento array quantità
                
    if($i!=0){ $n=$lunghezze_pezzi[$i-1]; //variabile per verifica valore maggiore
                
    }else $n=0//se sono al primo ciclo la variabile per la verifica del valore maggiore rimane a 0
                
    if($lunghezze_pezzi[$i] > $n && $quantita[$j] != 0){  //verifico che il pezzo abbia una lunghezza maggiore del precedente e che la sua quantità non sia 0
                    
    $n=$lunghezze_pezzi[$i]; //aggiungo la dimensione più lunga dei tubi da tagliare alla variabile di inserimento
                
    }
                if(
    $tubo $n){  //controllo che il tubo abbia la dimensione necessaria al taglio di quel pezzo
                    
    $tubo=$tubo-$n//taglio il tubo togliendo la quantità tagliata
                    
    $quantita[$j]=$quantita[$j]-1//diminuisco di 1 la quantità del tubo tagliato
                    
    array_push($tubo_corrente$n); //inserisco nell'array dei pezzi tagliati in ogni verga la dimensione del pezzo appena tagliato
                
    }else{
                    for(
    $k=0$k<count($lunghezze_pezzi); $k++){ //verifico se ci sono altri pezzi da poter tagliare nel tubo
                        
    if($tubo $lunghezze_pezzi[$k] && $quantita[$k] != 0$temp=1//se ce ne sono metto la variabile di controllo a 1
                        
    else{
                            
    $temp=0//se non ce ne sono la variabile andrà a 0
                            
    $verghe_tagl += 1//dato che il tubo è stato completamente tagliato, aumento la quantità delle verghe utilizzate di 1
                            
    array_push($sfridi$tubo);  //memorizzo lo sfrido della verga appena tagliata
                            
    $tubo 5800//riporto la variabile tubo alla lunghezza max dato che cambierò tubo
                        
    }
                    }
                    if(
    $temp=0){ //verifico che non ci siano più pezzi che ci possano stare nello sfrido
                        
    array_push($risultato$tubo_corrente); //inserisco l'array dei pezzi tagliati nel tubo all'interno dell'array che conterrà tutti i tubi tagliati
                        
    $tubo_corrente=array(); //riporto l'array del tubo corrente a 0 in modo che si possa iniziare un altro tubo da capo
                    
    }
                }
            }
        }
        for(
    $z=0$z<count($lunghezze_pezzi); $z++){ //controllo se ci sono ancora dei pezzi da tagliare
            
    if($quantita[$z] !=0$x=1//se ne restano altri metto la variabile x a 1
        
    }
        if(
    $x=0){
            echo 
    $risultato//stampo come vengono tagliati i tubi
            
    echo $verghe_tagl//stampo il numero di verghe utilizzate
        
    }
     
  6. macus_adi

    macus_adi Utente Attivo

    Registrato:
    5 Dicembre 2017
    Messaggi:
    962
    Mi Piace Ricevuti:
    56
    Punteggio:
    28
    Sesso:
    Maschio
    Occupazione:
    Developer
    Località:
    L'Aquila
    E se invece non ne resta nessuno?
    X è indefinita....
    Non puoi fare echo su oggetti/array....
    In definitiva provata e non funzionante...
    Non ho idea di cosa volessi fare con tutti quei cicli....
    Non mi piace.... Se rispecchia le tue esigenze OK!
    Altra nota, così come hai impostato il tutto cambiando l'ordinamento degli elementi hai questa situazione:
    PHP:
    $lunghezze_pezzi = array ("3000",  "500""800","2000"); //array lunghezze pezzi
    $quantita = array ("5""5""5""5"); //array quantità
    3000 500 500 500 500 500 = 300
    3000 800 800 800 800 = 400
    2000 2000 800 = 1000
    2000 2000 = 1800
    2000 = 3800
    etc.....

    Rispetto all'ottimizzazione
    3000 2000 800= 0
    3000 2000 800= 0
    3000 2000 800= 0
    3000 2000 800= 0
    3000 2000 800= 0
    500 500 500 500 500= 3300


    Non hai gestito l'ordinamento e la gestione delle posizioni per completare i tagli!

    Per fare la prova con ordinamento e senza ordinamento prova a modificare la classe che ti ho mandato commentando questa dalla linea 25 alla 32:
    PHP:
    /*foreach ($data as $k=>$v){
       (!isset($bs[$v[1]]))?$bs[$v[1]]=$v[0]:$bs[$v[1]]+=$v[0];
    }
    krsort($bs);
    $data=[];
    foreach ($bs as $k=>$v){
       $data[]=[$v,$k];
    }*/

     
    Ultima modifica: 10 Ottobre 2019 alle 12:31
  7. macus_adi

    macus_adi Utente Attivo

    Registrato:
    5 Dicembre 2017
    Messaggi:
    962
    Mi Piace Ricevuti:
    56
    Punteggio:
    28
    Sesso:
    Maschio
    Occupazione:
    Developer
    Località:
    L'Aquila
    Allego screen con e senza ordinamento così si vede la differenza...

    _Snap_giovedì 10 ottobre 2019_12h33m28s_003_.png
    _Snap_giovedì 10 ottobre 2019_12h33m09s_002_.png
     

    Files Allegati:

  8. Felotti

    Felotti Nuovo Utente

    Registrato:
    7 Ottobre 2019
    Messaggi:
    9
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    Hai ragione, ho sbagliato tutto praticamente :D
    Una sola domanda
    Come potrei memorizzare all'interno della matrice $data dei valori ricevuti con $_POST? (Ovviamente senza sapere quanti dati potrebbe inserire l'utente
     
  9. macus_adi

    macus_adi Utente Attivo

    Registrato:
    5 Dicembre 2017
    Messaggi:
    962
    Mi Piace Ricevuti:
    56
    Punteggio:
    28
    Sesso:
    Maschio
    Occupazione:
    Developer
    Località:
    L'Aquila
    Basta iterare i dati in post!
    Non ho idea di come tu abbia pensato il form!
     
  10. Felotti

    Felotti Nuovo Utente

    Registrato:
    7 Ottobre 2019
    Messaggi:
    9
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    Stavo utilizzando il tuo codice con i valori in $data inseriti manualmente e funziona correttamente in base alle mie esigenze.
    Ora sto provando a completare l'array con valori ricevuti da 'POST', organizzandomi in questo modo:

    PHP:
    $quantita $_POST['quantita'];
    $lunghezza $_POST['lunghezza'];

    $data = [ /*quantita*//*lunghezze*/ ]
    Solo che non riesco a far si che in $data ci vadano quantità e lunghezze come hai creato te la matrice manualmente.

    Mettiamo il caso che io riceva i seguenti valori da HTML:

    PHP:
    $quantita = (510101052025)
    $lunghezze = (10001200250015005003003000)
    Ora, come posso far si che la matrice si compili come segue?

    PHP:
    $data = [
    [
    51000],
    [
    101200],
    [
    102500],
    [
    101500],
    [
    5500],
    [
    20300],
    [
    253000]];
    In modo tale da non effettuare alcuna modifica al codice che mi hai fornito
     
  11. macus_adi

    macus_adi Utente Attivo

    Registrato:
    5 Dicembre 2017
    Messaggi:
    962
    Mi Piace Ricevuti:
    56
    Punteggio:
    28
    Sesso:
    Maschio
    Occupazione:
    Developer
    Località:
    L'Aquila
    PHP:
    $data=[];
    foreach(
    $quantita as $k=>$item)$data[]=[$item,$lunghezza[$k]];
     
  12. Felotti

    Felotti Nuovo Utente

    Registrato:
    7 Ottobre 2019
    Messaggi:
    9
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    Ho creato 3 file
    In uno chiedo il numero di codici differenti da dover tagliare, in modo che nel secondo file io possa far si che all'utente appaiano n richieste di lunghezze e quantità, che a loro volta verranno inviate al file con il quale calcolo il tutto.
    Purtroppo però non funziona e non ne capisco il motivo o_O
    Allego i 3 file
     

    Files Allegati:

  13. macus_adi

    macus_adi Utente Attivo

    Registrato:
    5 Dicembre 2017
    Messaggi:
    962
    Mi Piace Ricevuti:
    56
    Punteggio:
    28
    Sesso:
    Maschio
    Occupazione:
    Developer
    Località:
    L'Aquila
    Hai fatto un macello nei file.....
    Controller richiama la view
    PHP:
    public function createForm(){
       if(empty(
    $this->input->post())){
          
    $this->load->view('createForm');
       }else{
          
    $this->load->view('createLen',['data'=>$this->input->post('np')]);
       }
    }
    public function 
    parseRequest(){
       
    $data=[];
       foreach (
    $this->input->post('data')as $k=>$v){
          
    $data[]=[$v['qta'],$v['len']];
       }
       
    $opt=new Goptimeze();
       echo 
    $opt->creaLen($data)->html;
       
    print_r($opt->result);
    }
    View createForm
    Codice:
    <form method="post">
       <input type="number" name="np" min="0" max="20" class="form-control" required>
       <br>
       <button type="submit">invia</button>
    </form>
    
    View createLen
    Codice:
    <form action="/CONTROLLER/parseRequest" method="post">
    <table>
       <thead>
       <tr>
          <th></th>
          <th>Lunghezza</th>
          <th>Qauntità</th>
       </tr>
       </thead>
       <tbody>
       <?php
       for($i=0;$i<$data;$i++){
          echo '<tr><td>'.($i+1).'</td>
             <td><input type="number" min="0" required max="5800" name="data['.$i.'][len]"></td>
             <td>
             <input type="number" min="0" required max="5800" name="data['.$i.'][qta]"></td>
             </td>';
    
       }
       ?>
       </tbody>
       <tfoot>
       <tr>
          <th colspan="3">
             <button type="submit">Salva</button>
          </th>
       </tr>
       </tfoot>
    </table>
    </form>
    
     
    A Felotti piace questo elemento.
  14. Felotti

    Felotti Nuovo Utente

    Registrato:
    7 Ottobre 2019
    Messaggi:
    9
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    Ecco il perchè o_O
    Solo che non riesco a capire in quali file inserire questi codici
     
  15. macus_adi

    macus_adi Utente Attivo

    Registrato:
    5 Dicembre 2017
    Messaggi:
    962
    Mi Piace Ricevuti:
    56
    Punteggio:
    28
    Sesso:
    Maschio
    Occupazione:
    Developer
    Località:
    L'Aquila
    ???????

    I due metodi nel controller
    Crea due file di view:
    1. createForm.php
    2. createLen.php
     
  16. Felotti

    Felotti Nuovo Utente

    Registrato:
    7 Ottobre 2019
    Messaggi:
    9
    Mi Piace Ricevuti:
    0
    Punteggio:
    1
    Sesso:
    Maschio
    Perfetto, io ora ho questi 3 file che trovi nell'allegato.

    CreateForm.php
    ParseRequest.php
    risultato.php

    I primi due funzionano correttamente
    Il problema lo riscontro nell'ottenere il risultato finale in quanto non mi ritorna nulla.
    Riesci a darmi questo ultimo aiuto?
    Mi salveresti la vita:rolleyes:

    Scusa la mia ignoranza e ti ringazio tantissimo per il tempo che mi stai dedicando, ma credo che mi sto creando dei complessi che non mi portano a nulla
     

    Files Allegati:

    • Invio.zip
      Dimensione del file:
      1,7 KB
      Visite:
      0
    Ultima modifica: 15 Ottobre 2019 alle 14:03
Sto caricando...

Condividi questa Pagina