none
Evitar pasar por tantas iteraciones del ciclo for RRS feed

  • Pregunta

  • Buen día,

    Tengo un vector de byte de tres dimensiones.

    Mi idea recorrer todas las combinaciones posibles, es decir, ir probando diferentes valores dentro del vector hasta que no quede ninguna combinación posible que no haya pasado. No uso el límite de 255 de los bytes, sino uno establecido por el usuario (ejemplo: 8). No puedo usar un ciclo for que recorra todas las posibilidades porque tarda demasiado . Lo que busco con esto, son ciertas combinaciones que cumplan ciertos requisitos (la unica que nos importa es que la suma de todos los valores debe dar cierto numero conocido)

    Mi idea es esta:

    Si yo tuviera un ciclo for tendría un int i que podríamos verlo como el numero de intento. Lo que yo pienso es que este numero se podría corresponder a una posibilidad de combinación dentro de este vector (es decir, cada vez que el ciclo for avanza, aumenta un valor en el vector, y a la vez aumenta el int i que es el número de intento).

    Mi pregunta es: ¿como puedo convertir este número de intento a una combinación de valores en el vector?

    private void main()
    {
      //Intetando con for:
      
      int maximoValor = 8; //por ejemplo
      
      int cantidadValoresX = 15, cantidadValoresY = 10, cantidadValoresZ = 10;
      
      byte[,,] valores = new byte[cantidadValoresX, cantidadValoresY, cantidadValoresZ];
      
      int numeroIntento = 0;
      for (int i = 0; i < 15; i++)
        {
        for (int j = 0; j < 10; j++)
          {
          for (int k = 0; k < 10; k++)
            {
            for (byte m = 1; m <= maximoValor; m++)
              {
                valores[i, j, k] = m;
                comprobar();
                numeroIntento++;
              }
            }
         }
       }
    
      //pero podría ser
      int numeroMagico = ObtenerNumeroMagico(); //es un número que obtengo de otras cuentas basadas en las condiciones
      
      while(true)
      {
        valores = ObtenerValoresDelIntentoNumero(numeroMagico); //obtengo el valor que hubiera obtenido si hubiera hecho el ciclo for n veces
        comprobar(); //compruebo que son validos
        if (boolfinished) //si es correcto este bool deberia ser verdadero
        {
           break;
        }
      }
    }



    • Editado Somanoss domingo, 21 de enero de 2018 21:49 no se entendía bien
    domingo, 21 de enero de 2018 19:42

Respuestas

  • Si tu idea es recorrer todas las combinaciones o  es una especificación : solo hay una solución, que es recorrer todas las combinaciones y el motivo de esto son dos cosas:

    1.- Necesitas todas las soluciones. (aunque no las haya);

    2.- Necesitas mínimo 1 solución (que podría ser la última combinación)

    Por logica n soluciones mínimo es lo mismo que la posibilidad 1 o 2 donde Todas en N en el caso de 1.- o n es minimo 1 en el caso de 2.-

    Bueno dicho esto y leyendo lo que pides entiendo que tu problema es como el punto 2.- necesitas minimo encontrar la primera solución, y eso es tan senzillo como recorrer con for , while como tu quieras mientras no la encuentres y la forma de romper el recorrido es mediante Flag (variable de control) o break salir del bucle.

    Te pongo la solución a tu problema por flag y rotura (break) de bucle for:

    int numeroIntento = 0;

    bool control = false; for (int i = 0; i < 15; i++) { for (int j = 0; j < 10; j++) { for (int k = 0; k < 10; k++) { for (byte m = 1; m <= maximoValor; m++) { valores[i, j, k] = m; control = comprobar(); // si devuelve true es correcto y saiimos.

    if( control ) break; numeroIntento++; } if( control ) break; } } if( control ) break;

    }

    lunes, 22 de enero de 2018 20:32
  • hola

    pregunta, porque usaste un array de tres dimensiones? no podrias haber creado una clase como ser

    public class Item { public int Val1 {get;set;} public int Val2 {get;set;} public int Val3 {get;set;}

    public int Suma {

    get { return this.Val1 + this.Val2 + this.Val3; }

    } }

    de esta forma podrias podrias validar son una simple linea de linq cual es el valor que buscas

    List<Item> Items = new List<Item>();
    
    //aqui cargas los items
    
    var result = Items.First(x=> x.Suma == valor);


    asi de simple puedes trabjar con clase

    de ser pisible evita usar array es para problemas, trabaja orientado a objetos

    saludis


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    lunes, 22 de enero de 2018 21:02

Todas las respuestas

  • Si tu idea es recorrer todas las combinaciones o  es una especificación : solo hay una solución, que es recorrer todas las combinaciones y el motivo de esto son dos cosas:

    1.- Necesitas todas las soluciones. (aunque no las haya);

    2.- Necesitas mínimo 1 solución (que podría ser la última combinación)

    Por logica n soluciones mínimo es lo mismo que la posibilidad 1 o 2 donde Todas en N en el caso de 1.- o n es minimo 1 en el caso de 2.-

    Bueno dicho esto y leyendo lo que pides entiendo que tu problema es como el punto 2.- necesitas minimo encontrar la primera solución, y eso es tan senzillo como recorrer con for , while como tu quieras mientras no la encuentres y la forma de romper el recorrido es mediante Flag (variable de control) o break salir del bucle.

    Te pongo la solución a tu problema por flag y rotura (break) de bucle for:

    int numeroIntento = 0;

    bool control = false; for (int i = 0; i < 15; i++) { for (int j = 0; j < 10; j++) { for (int k = 0; k < 10; k++) { for (byte m = 1; m <= maximoValor; m++) { valores[i, j, k] = m; control = comprobar(); // si devuelve true es correcto y saiimos.

    if( control ) break; numeroIntento++; } if( control ) break; } } if( control ) break;

    }

    lunes, 22 de enero de 2018 20:32
  • hola

    pregunta, porque usaste un array de tres dimensiones? no podrias haber creado una clase como ser

    public class Item { public int Val1 {get;set;} public int Val2 {get;set;} public int Val3 {get;set;}

    public int Suma {

    get { return this.Val1 + this.Val2 + this.Val3; }

    } }

    de esta forma podrias podrias validar son una simple linea de linq cual es el valor que buscas

    List<Item> Items = new List<Item>();
    
    //aqui cargas los items
    
    var result = Items.First(x=> x.Suma == valor);


    asi de simple puedes trabjar con clase

    de ser pisible evita usar array es para problemas, trabaja orientado a objetos

    saludis


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    lunes, 22 de enero de 2018 21:02
  • Leando si hace eso que proponenes le dara un error cuando no encuentre el valor en la lista. 

    martes, 23 de enero de 2018 5:18