import { Katex } from './Katex' import { fillDot, drawSemiplane, drawSimpleArrow } from './lib-v2/canvas' import { range } from './lib-v2/math' import { Matrix } from './lib-v2/matrix' import { Rational } from './lib-v2/rationals' import { ProblemComment, computePrimalSimplexSteps } from './lib-v2/ro/primal-simplex' import { Vector } from './lib-v2/vector' import { MiniMark } from './MiniMark' import { ProblemInput } from './parser-problem' // type Step = { // B: number[] // } // const activeIndices = (input: ProblemInput, x: Vector): number[] => { // const { A, b } = input // const A_x = A.apply(x) // return A_x.getData().flatMap((a, i) => (a.eq(b.at(i)) ? [i] : [])) // } const PrimalStep = ({ iter, A, b, c, B, x, xi, comments, }: { iter: number A: Matrix b: Vector c: Vector B: number[] x?: Vector xi?: Vector comments: ProblemComment[] }) => { return (

Iterazione {iter + 1} dell'algoritmo

{comments.map(comment => comment.type === 'formula' ? (
) : (
) )}
) } export const Primale = ({ input }: { input: ProblemInput }) => { // const steps: Step[] = [{ B: input.B }] const problemOutput = computePrimalSimplexSteps({ A: input.A, b: input.b, c: input.c, B: input.B, maxIterations: 10, }) return (
{problemOutput.steps.map((step, iter) => ( ))}
) } const PrimalCanvas = ({ A, b, c, B, x, xi, }: { A: Matrix b: Vector c: Vector B: number[] x?: Vector xi?: Vector }) => { const render = ($canvas: HTMLCanvasElement | null) => { if (!$canvas) { return } $canvas.width = $canvas.offsetWidth $canvas.height = $canvas.offsetHeight const g = $canvas.getContext('2d') if (!g) { throw new Error('Could not get 2d context') } const width = $canvas.width const height = $canvas.height g.clearRect(0, 0, width, height) g.strokeStyle = '#333' g.lineWidth = 2 g.lineCap = 'round' g.lineJoin = 'round' g.fillStyle = '#333' g.font = 'bold 16px sans-serif' g.textAlign = 'center' g.textBaseline = 'middle' // // draw y axis arrow // g.beginPath() // g.moveTo(width / 2, height / 2) // g.lineTo(width / 2, 5) // g.lineTo(width / 2 - 10, 15) // g.moveTo(width / 2, 5) // g.lineTo(width / 2 + 10, 15) // g.stroke() // // draw x axis arrow // g.beginPath() // g.moveTo(width / 2, height / 2) // g.lineTo(width - 5, height / 2) // g.lineTo(width - 15, height / 2 - 10) // g.moveTo(width - 5, height / 2) // g.lineTo(width - 15, height / 2 + 10) // g.stroke() // draw c vector const [c1, c2] = c.getData() const cLen = Math.sqrt(c1.toNumber() ** 2 + c2.toNumber() ** 2) // g.save() g.strokeStyle = 'darkgreen' g.lineWidth = 2 drawSimpleArrow( g, 50, height - 50, 50 + (c1.toNumber() / cLen) * 40, height - 50 - (c2.toNumber() / cLen) * 40, 5 ) g.fillStyle = 'darkgreen' fillDot(g, 50, height - 50, 4) g.fillText(`c`, 50 - (c1.toNumber() / cLen) * 20, height - 50 + (c2.toNumber() / cLen) * 20) // g.beginPath() // g.translate(50, height - 50) // g.rotate(Math.atan2(c2.toNumber(), c1.toNumber())) // g.moveTo(0, 0) // g.lineTo(30, 0) // g.moveTo(30, 0) // g.lineTo(25, -5) // g.moveTo(30, 0) // g.lineTo(25, 5) // g.stroke() // g.restore() // g.fillStyle = '#333' // g.font = '16px sans-serif' // g.textAlign = 'center' // g.textBaseline = 'middle' // g.fillText(`A = ${A}`, width / 2, height / 2) g.translate(width / 2, height / 2) g.scale(width / 2, -width / 2) g.scale(1 / 10, 1 / 10) // draw semiplanes // draw semiplanes not in B range(0, A.rows) .filter(i => !B.includes(i)) .forEach(i => { const [a1, a2] = A.rowAt(i).getData() const b_i = b.at(i) drawSemiplane(g, a1.toNumber(), a2.toNumber(), b_i.toNumber()) }) // draw semiplanes in B B.forEach(i => { const [a1, a2] = A.rowAt(i).getData() const b_i = b.at(i) drawSemiplane(g, a1.toNumber(), a2.toNumber(), b_i.toNumber(), { lineColor: '#040', lineWidth: 3, }) }) // draw current solution if (x) { const [x1, x2] = x.getData() g.lineWidth = 30 / g.canvas.width g.strokeStyle = 'darkgreen' drawSimpleArrow( g, x1.toNumber(), x2.toNumber(), x1.toNumber() + c1.toNumber() / cLen, x2.toNumber() + c2.toNumber() / cLen, 0.125 ) // draw xi if (xi) { const [xi1, xi2] = xi.getData() const xiLen = Math.sqrt(xi1.toNumber() ** 2 + xi2.toNumber() ** 2) g.strokeStyle = '#44d' g.lineWidth = 50 / g.canvas.width drawSimpleArrow( g, x1.toNumber(), x2.toNumber(), x1.toNumber() + xi1.toNumber() / xiLen, x2.toNumber() + xi2.toNumber() / xiLen, 0.125 ) } g.fillStyle = '#d44' fillDot(g, x1.toNumber(), x2.toNumber(), 0.2) } } return } // export const PrimaleStep = ({ input, step }: { input: ProblemInput; step: Step }) => { // const { A, b, c } = input // const rows = [] // const canvasOptions: Parameters[0] = { A, b, c, B: step.B } // const A_B = A.slice({ rows: step.B }) // const A_B_inverse = A_B.inverse2x2() // const b_B = b.slice(step.B) // rows.push( //
// //
// ) // const x = A_B_inverse.apply(b_B) // canvasOptions.x = x // rows.push( //
// //
// ) // const y_Zero = Vector.zero(RationalField, A.rows) // const y = y_Zero.with(step.B, y_B) // rows.push( //
// //
// ) // const I_x = activeIndices(input, x) // rows.push( //
// . //

//

// La soluzione duale è {isDualAdmissible ? 'ammissibile' : 'non ammissibile'} e{' '} // {isDualDegenerate ? 'degenere' : 'non degenere'}. //

//
// ) // if (!isDualAdmissible) { // const h = Math.min(...y.getData().flatMap((y, i) => (y.lt(RationalField.zero) ? [i] : []))) // rows.push( //
// //
// ) // const N = range(0, A.rows).filter(i => !step.B.includes(i)) // const A_N = A.slice({ rows: N }) // const A_N__xi = A_N.apply(xi) // rows.push( //
// //
// ) // if (!A_N__xi.getData().every(x => x.leq(RationalField.zero))) { // const positiveIndices = N.filter(i => A_N__xi.at(A_N.forwardRowIndices[i]).gt(RationalField.zero)) // const [k, lambda] = positiveIndices // .map<[number, Rational]>(i => [i, b.at(i).sub(A.rowAt(i).dot(x)).div(A.rowAt(i).dot(xi))]) // .reduce(([i1, lambda1], [i2, lambda2]) => (lambda2.lt(lambda1) ? [i2, lambda2] : [i1, lambda1])) // rows.push( //
// 0 \\right\\}`, // `${lambda}`, // ].join(' = ')} // /> //
// ) // rows.push( //
// 0 \\right\\}`, // `${k + 1}`, // ].join(' = ')} // /> //
// ) // rows.push( //
// i !== h), k].toSorted())}`, // ].join(' = ')} // /> //
// ) // } else { // rows.push( //
//

// La soluzione duale è illimitata. //

//
// ) // } // } // return ( //
//
{rows}
//
// //
//
// ) // }