Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

209
Vistas
Encuentre fracciones con denominador común para áreas de parcela, la suma debe permanecer igual

Digamos que tengo una parcela (un terreno) de 8027 metros cuadrados y tengo más de un propietario, pero no tienen la misma cantidad de terreno.

Dueño A tiene: 1003.5m2 Dueño B tiene: 1003.5m2 Dueño C tiene 1337m2 Dueño D tiene 1338m2 Dueño E tiene 1338m2 Dueño F tiene 2007m2

Como salida, quiero obtener una fracción de números enteros con el mínimo común denominador posible, etc.

1/8 1/8 .. .. ..

Sé que es muy poco probable que sea tan pequeño...

pero cuando divide fracciones, la diferencia no debe exceder más de +/- 1m2 por propietario

lo que significa que si el propietario A tiene 1003,5 m2 al principio, y tengo 1/8 8027/8 = 1003,35, está bien, PERO, desafortunadamente grande, ¡PERO! La SUMA total de todos los propietarios debe permanecer igual al final :(

Por ahora, pude obtener el mínimo común denominador para los propietarios individualmente y ni siquiera estoy seguro de cuál es el siguiente paso para obtener el resultado deseado ...

¡Cualquier ayuda es muy apreciada!

 gcd = function (a, b) { if (b < 0.0000001) return a; // Since there is a limited precision we need to limit the value. return gcd(b, Math.floor(a % b)); // Discard any fractions due to limitations in precision. }; var total_area = 8027; var area_parts = [1003.5, 1003.5, 1337, 1338, 1338, 2007]; ResaultArr = Array(); for (let i = 0; i < area_parts.length; i++) { var decimal_fraction = area_parts[i] / total_area; var denominator = Math.pow(10, 4); var numerator = decimal_fraction * denominator; var divisor = gcd(numerator, denominator); numerator /= divisor; denominator /= divisor; var fraction = Math.floor(numerator) + '/' + Math.floor(denominator); var decimal_fraction_after = Math.floor(numerator) / Math.floor(denominator); var area_difference = area_parts[i] - (total_area * decimal_fraction_after); var area_part_after = total_area * decimal_fraction_after; ResaultArr[i] = { area_difference: area_difference, fraction: fraction, decimal_fraction: decimal_fraction, decimal_fraction_after: decimal_fraction_after, area_part: area_parts[i], area_part_after: area_part_after, total_area: total_area }; } console.log(ResaultArr);
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Un enfoque de fuerza bruta simplemente prueba denominadores sucesivos hasta que encuentra uno que funcione:

 const makeFractions = (xs, tolerance = 1, n = xs .length) => { const total = xs .reduce ((a, b) => a + b, 0) const numerators = xs .map (x => Math .round (x * n / total)) const denom = numerators .reduce ((a, b) => a + b, 0) const candidates = numerators .map (y => y * total / denom) return candidates .some ((y, i) => Math .abs (y - xs [i]) > tolerance) ? makeFractions (xs, tolerance, n + 1) : numerators .map (y => `${y}/${denom}`) } const parts = [1003.5, 1003.5, 1337, 1338, 1338, 2007], total = 8027 const results = makeFractions (parts) console .log ('parts: ', parts) console .log ('fractions:', results) console .log ('exact values: ', results .map ( s => s .split('/').map (Number)) .map (([n, d]) => n * total / d ))
 .as-console-wrapper {max-height: 100% !important; top: 0}

Aquí comenzamos con n de 6 , la longitud de la matriz, y luego redondeamos los valores por cuántos sextos 6 total se aproximan, obteniendo numeradores potenciales de [1, 1, 1, 1, 1, 2] , que totaliza para darnos un denominador de 7 y un desglose de candidatos de [1146.7142857142858, 1146.7142857142858, 1146.7142857142858, 1146.7142857142858, 1146.7142857142858, 2293.4285714285716] Al menos uno de estos está demasiado lejos de nuestros números objetivo; de hecho, todos lo están, en este caso, por lo que intentamos nuevamente con 7 para n . Obtenemos el mismo desglose y nuevamente el mismo desglose para 8 . Cuando llegamos a 9 , obtenemos un denominador de 9 y candidatos de [891.8888888888889, 891.8888888888889, 891.8888888888889, 1783.7777777777778, 1783.7777777777778, 1783.7777777777778]} Estos todavía están demasiado lejos, y seguimos intentándolo. Eventualmente, llegamos a n de 22 , lo que nos da numeradores potenciales de [3, 3, 4, 4, 4, 6]] , y por lo tanto un denominador de 24 con valores candidatos de [1003.375, 1003.375, 1337.8333333333333, 1337.8333333333333, 1337.8333333333333, 2006.75] . Cada uno de estos está dentro de nuestra tolerancia de 1 de los números objetivo y nos detenemos aquí, devolviendo las fracciones [3/24, 3/24, 4/24, 4/24, 4/24, 6/24] .


Probablemente tenga sentido extraer una función de sum y almacenar el total calculado que no cambiará por invocación recursiva, por lo que quizás sea un poco más limpio:

 const sum = (ns) => ns .reduce ((a, b) => a + b, 0) const makeFractions = (xs, tolerance = 1, total = sum (xs), n = xs .length) => { const numerators = xs .map (x => Math .round (x * n / total)) const denom = sum (numerators) const candidates = numerators .map (y => y * total / denom) return candidates .some ((y, i) => Math .abs (y - xs [i]) > tolerance) ? makeFractions (xs, tolerance, total, n + 1) : numerators .map (y => `${y}/${denom}`) }
about 4 years ago · Juan Pablo Isaza Denunciar

0

En tu ejemplo, las proporciones son aproximadamente 1/8, 1/8, 1/6, 1/6, 1/6 y 1/4, podemos darles un denominador común de 24, por lo que las fracciones se convierten en 3/24, 3 /24, 4/24, 4/24 y 6/24 dando áreas 1003.375, 1003.375,1337.833333,1337.833333,1337.833333, 2006.75 que suman exactamente 8027.

Esto nos da una idea de cómo definir mejor el problema. Encuentre el conjunto de fracciones a/n, b/n, c/n, d/n, e/n, f/n tales que su suma sea 1 y que el producto 8027 * a/n esté dentro de los límites de error deseados. por ejemplo | 8027*a/n - 1003.5 | < cota, etc. Encuentre el n más pequeño que satisfaga esta propiedad.

Un enfoque simple es trabajar iterativamente en n.

 for(n=1;n<limit;++n) { a = round(n * 1003.5 / 8027); b = round(n * 1003.5 / 8027); c = round(n * 1337 / 8027); d = round(n * 1338 / 8027); e = round(n * 1338 / 8027); f = round(n * 2007 / 8027); errA = abs(8027*a/n - 1003.5); .... if(a+b+c+d+e+f==n && errA < bound && ... ) break; }
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda