Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

203
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!