// Numbas version: finer_feedback_settings {"questions": [], "duration": 0, "name": "Linear programming", "showQuestionGroupNames": false, "allQuestions": true, "percentPass": 0, "feedback": {"showanswerstate": true, "advicethreshold": 0, "showactualmark": true, "allowrevealanswer": true, "showtotalmark": true, "enterreviewmodeimmediately": true, "showexpectedanswerswhen": "inreview", "showpartfeedbackmessageswhen": "always", "showactualmarkwhen": "always", "showtotalmarkwhen": "always", "showanswerstatewhen": "always", "showadvicewhen": "never"}, "shuffleQuestions": false, "question_groups": [{"pickingStrategy": "all-ordered", "questions": [{"name": "Sensitivity analysis of a linear programming problem", "extensions": ["jsxgraph", "optimisation"], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "contributors": [{"name": "Newcastle University Mathematics and Statistics", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/697/"}], "variable_groups": [{"variables": [], "name": "Testing"}, {"variables": ["product_baseline", "x_bound", "y_bound", "resource_baseline", "profit_baseline"], "name": "Order of magnitude"}, {"variables": ["x_intercept_a", "y_intercept_a"], "name": "Constraint setup"}, {"variables": ["minimum_x", "minimum_y", "x_resource", "y_resource", "total_resource", "profit_x", "profit_y"], "name": "Final constraints"}, {"variables": ["x_intercept", "y_intercept", "inequality_coordinates"], "name": "Diagram data"}, {"variables": ["program", "best", "line_is_binding", "best_coords", "binding_lines"], "name": "Optimal solution"}, {"variables": ["line_names", "change_description", "line_prepositions"], "name": "Text"}, {"variables": ["nonbinding_line", "change", "changing_affects_solution"], "name": "Relax or tighten"}], "variables": {"resource_baseline": {"templateType": "anything", "group": "Order of magnitude", "definition": "repeat(\n 10^random(0..1)*random(1..9)*y_bound,\n 2\n)", "description": "", "name": "resource_baseline"}, "profit_baseline": {"templateType": "anything", "group": "Order of magnitude", "definition": "10^random(1,1,1,2,2,3)", "description": "", "name": "profit_baseline"}, "binding_lines": {"templateType": "anything", "group": "Optimal solution", "definition": "filter(line_is_binding[j],j,0..3)", "description": "", "name": "binding_lines"}, "line_is_binding": {"templateType": "anything", "group": "Optimal solution", "definition": "binding_lines(program)", "description": "", "name": "line_is_binding"}, "changing_affects_solution": {"templateType": "anything", "group": "Relax or tighten", "definition": "[\n best_coords[0]*x_resource[0]+best_coords[1]*y_resource[0]>total_resource[0]*change-0.0001,\n best_coords[0]*x_resource[1]+best_coords[1]*y_resource[1]>total_resource[1]*change-0.0001,\n best_coords[0]Graph goes here

", "scripts": {}, "type": "information", "showCorrectAnswer": true, "variableReplacementStrategy": "originalfirst", "variableReplacements": [], "marks": 0}, {"displayType": "radiogroup", "minMarks": 0, "layout": {"type": "all", "expression": ""}, "choices": ["{capitalise(line_names[0])}", "{capitalise(line_names[1])}", "{capitalise(line_names[2])}", "{capitalise(line_names[3])}"], "showCorrectAnswer": true, "matrix": "map(if(binding,[1,0],[0,1]),binding,line_is_binding)", "prompt": "

Which of the constraints are binding?

", "type": "m_n_x", "maxAnswers": 0, "shuffleChoices": false, "warningType": "none", "scripts": {}, "marks": 0, "minAnswers": 0, "maxMarks": 0, "shuffleAnswers": false, "variableReplacementStrategy": "originalfirst", "variableReplacements": [], "answers": ["Binding", "Non-binding"]}, {"displayType": "radiogroup", "choices": ["

Yes

", "

No

"], "showCorrectAnswer": true, "matrix": "if(changing_affects_solution,[1,0],[0,1])", "prompt": "

Suppose the {line_names[nonbinding_line]} {change_description}. Would that affect the optimal solution?

", "distractors": ["", ""], "shuffleChoices": false, "scripts": {}, "minMarks": 0, "type": "1_n_2", "maxMarks": 0, "displayColumns": 0, "variableReplacementStrategy": "originalfirst", "variableReplacements": [], "marks": 0}], "statement": "

A factory manufractures two products, X and Y. Existing demand means the factory must produce at least {minimum_x} units of product X and {minimum_y} units of product Y.

\n

A unit of X requires {x_resource[0]} units of resource 1 and {x_resource[1]} units of resource 2.

\n

A unit of Y requires {y_resource[0]} units of resource 1 and {y_resource[1]} units of resource 2.

\n

Each unit of product X sold earns £{profit_x} profit, and each unit of product Y sold earns £{profit_y} profit.

", "tags": ["linear programming", "MAS1901", "sensitivity analysis"], "rulesets": {}, "preamble": {"css": "", "js": "var optimisation = Numbas.extensions.optimisation;\n\nquestion.onHTMLAttached(function() {\n with(question.unwrappedVariables) {\n var result = optimisation.linear_programming_board({\n x_bound: x_bound,\n y_bound: y_bound,\n objective_line_coordinates: [-(minimum_x*profit_x + minimum_y*profit_y),profit_x,profit_y],\n minimum_x: minimum_x,\n minimum_y: minimum_y,\n inequality_1_coordinates: inequality_coordinates[0],\n inequality_2_coordinates: inequality_coordinates[1],\n coord_point: false\n });\n result.inequality_line_1.setAttribute({fixed:false, withLabel:true, name: 'Resource 1'});\n result.inequality_line_2.setAttribute({fixed:false, withLabel:true, name: 'Resource 2'});\n result.x_constraint_line.setAttribute({fixed:false});\n result.y_constraint_line.setAttribute({fixed:false});\n \n var board = result.board;\n \n var shadow_inequality_line_1 = board.create('line',inequality_coordinates[0],{withLabel:false,color:'lightgray', highlight: false, fixed: true});\n var shadow_inequality_line_2 = board.create('line',inequality_coordinates[1],{withLabel:false,color:'lightgray', highlight: false, fixed: true});\n var shadow_x_constraint_line = board.create('line',[[minimum_x,0],[minimum_x,1]],{withLabel:false,color:'lightgray', highlight: false, fixed: true});\n var shadow_y_constraint_line = board.create('line',[[0,minimum_y],[1,minimum_y]],{withLabel:false,color:'lightgray', highlight: false, fixed: true});\n shadow_inequality_line_1.visProp.layer = 1;\n shadow_inequality_line_2.visProp.layer = 1;\n shadow_x_constraint_line.visProp.layer = 1;\n shadow_y_constraint_line.visProp.layer = 1;\n \n board.update();\n \n window.result = result;\n\n $(question.display.html).find('.lp-graph').html('').append(result.div);\n \n }\n});"}, "type": "question", "metadata": {"notes": "", "licence": "Creative Commons Attribution 4.0 International", "description": "

Student is shown a linear programming problem, with graphical solution. 

\n

Asked to identify binding constraints, and decide if the optimal solution is changed by a named constraint either doubling or halving.

"}, "variablesTest": {"condition": "", "maxRuns": "100"}, "advice": "

a)

\n

The optimal solution is found at the intersection of the lines representing {line_names[binding_lines[0]]} and {line_names[binding_lines[1]]}. These constraints are binding; the other constraints are non-binding.

\n

b)

\n

If the {line_names[nonbinding_line]} {change_description}, the optimal solution found earlier ends up {line_prepositions[1][nonbinding_line]} the line representing the {line_names[nonbinding_line]}, making it invalidis still {line_prepositions[0][nonbinding_line]} the line representing the {line_names[nonbinding_line]}, so the optimal solution is not affected.

"}, {"name": "Solve a linear programming problem", "extensions": ["jsxgraph", "optimisation"], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "contributors": [{"name": "Bill Foster", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/6/"}, {"name": "Chris Graham", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/369/"}, {"name": "Newcastle University Mathematics and Statistics", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/697/"}], "parts": [{"showCorrectAnswer": true, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "prompt": "

Let $x$, $y$ be the number of units of {product_1s} and {product_2s} produced, respectively.

\n

What are the constraints on production resulting from the existing orders?

\n

$x \\geq$ [[0]]

\n

$y \\geq$ [[1]]

", "unitTests": [], "sortAnswers": false, "scripts": {}, "gaps": [{"correctAnswerFraction": false, "allowFractions": false, "customMarkingAlgorithm": "", "mustBeReduced": false, "extendBaseMarkingAlgorithm": true, "minValue": "xconstraint", "maxValue": "xconstraint", "unitTests": [], "correctAnswerStyle": "plain", "showFeedbackIcon": true, "scripts": {}, "notationStyles": ["plain", "en", "si-en"], "type": "numberentry", "variableReplacementStrategy": "originalfirst", "showCorrectAnswer": true, "variableReplacements": [], "marks": 1, "mustBeReducedPC": 0}, {"correctAnswerFraction": false, "allowFractions": false, "customMarkingAlgorithm": "", "mustBeReduced": false, "extendBaseMarkingAlgorithm": true, "minValue": "yconstraint", "maxValue": "yconstraint", "unitTests": [], "correctAnswerStyle": "plain", "showFeedbackIcon": true, "scripts": {}, "notationStyles": ["plain", "en", "si-en"], "type": "numberentry", "variableReplacementStrategy": "originalfirst", "showCorrectAnswer": true, "variableReplacements": [], "marks": 1, "mustBeReducedPC": 0}], "type": "gapfill", "variableReplacementStrategy": "originalfirst", "variableReplacements": [], "marks": 0, "showFeedbackIcon": true}, {"showCorrectAnswer": true, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "prompt": "

Now enter the constraints given by the availability of {resource_1} and {resource_2}:

\n

{capitalise(resource_1)}: [[0]] $x + $ [[1]] $y \\le $ [[2]]

\n

{capitalise(resource_2)}: [[3]] $x + $ [[4]] $y \\le $ [[5]]

", "unitTests": [], "sortAnswers": false, "scripts": {}, "gaps": [{"correctAnswerFraction": false, "allowFractions": false, "customMarkingAlgorithm": "", "mustBeReduced": false, "extendBaseMarkingAlgorithm": true, "minValue": "resource1x", "maxValue": "resource1x", "unitTests": [], "correctAnswerStyle": "plain", "showFeedbackIcon": true, "scripts": {}, "notationStyles": ["plain", "en", "si-en"], "type": "numberentry", "variableReplacementStrategy": "originalfirst", "showCorrectAnswer": true, "variableReplacements": [], "marks": 1, "mustBeReducedPC": 0}, {"correctAnswerFraction": false, "allowFractions": false, "customMarkingAlgorithm": "", "mustBeReduced": false, "extendBaseMarkingAlgorithm": true, "minValue": "resource1y", "maxValue": "resource1y", "unitTests": [], "correctAnswerStyle": "plain", "showFeedbackIcon": true, "scripts": {}, "notationStyles": ["plain", "en", "si-en"], "type": "numberentry", "variableReplacementStrategy": "originalfirst", "showCorrectAnswer": true, "variableReplacements": [], "marks": 1, "mustBeReducedPC": 0}, {"correctAnswerFraction": false, "allowFractions": false, "customMarkingAlgorithm": "", "mustBeReduced": false, "extendBaseMarkingAlgorithm": true, "minValue": "totalresource1", "maxValue": "totalresource1", "unitTests": [], "correctAnswerStyle": "plain", "showFeedbackIcon": true, "scripts": {}, "notationStyles": ["plain", "en", "si-en"], "type": "numberentry", "variableReplacementStrategy": "originalfirst", "showCorrectAnswer": true, "variableReplacements": [], "marks": 1, "mustBeReducedPC": 0}, {"correctAnswerFraction": false, "allowFractions": false, "customMarkingAlgorithm": "", "mustBeReduced": false, "extendBaseMarkingAlgorithm": true, "minValue": "resource2x", "maxValue": "resource2x", "unitTests": [], "correctAnswerStyle": "plain", "showFeedbackIcon": true, "scripts": {}, "notationStyles": ["plain", "en", "si-en"], "type": "numberentry", "variableReplacementStrategy": "originalfirst", "showCorrectAnswer": true, "variableReplacements": [], "marks": 1, "mustBeReducedPC": 0}, {"correctAnswerFraction": false, "allowFractions": false, "customMarkingAlgorithm": "", "mustBeReduced": false, "extendBaseMarkingAlgorithm": true, "minValue": "resource2y", "maxValue": "resource2y", "unitTests": [], "correctAnswerStyle": "plain", "showFeedbackIcon": true, "scripts": {}, "notationStyles": ["plain", "en", "si-en"], "type": "numberentry", "variableReplacementStrategy": "originalfirst", "showCorrectAnswer": true, "variableReplacements": [], "marks": 1, "mustBeReducedPC": 0}, {"correctAnswerFraction": false, "allowFractions": false, "customMarkingAlgorithm": "", "mustBeReduced": false, "extendBaseMarkingAlgorithm": true, "minValue": "totalresource2", "maxValue": "totalresource2", "unitTests": [], "correctAnswerStyle": "plain", "showFeedbackIcon": true, "scripts": {}, "notationStyles": ["plain", "en", "si-en"], "type": "numberentry", "variableReplacementStrategy": "originalfirst", "showCorrectAnswer": true, "variableReplacements": [], "marks": 1, "mustBeReducedPC": 0}], "type": "gapfill", "variableReplacementStrategy": "originalfirst", "variableReplacements": [], "marks": 0, "showFeedbackIcon": true}, {"showCorrectAnswer": true, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "prompt": "

Given the information on profits for {product_1s} and {product_2s}, write down the objective function which is to be maximised: [[0]]

", "unitTests": [], "sortAnswers": false, "scripts": {}, "gaps": [{"answer": "{profitx}*x+{profity}*y", "showCorrectAnswer": true, "extendBaseMarkingAlgorithm": true, "customMarkingAlgorithm": "", "checkingType": "absdiff", "vsetRangePoints": 5, "failureRate": 1, "checkVariableNames": false, "unitTests": [], "vsetRange": [0, 1], "type": "jme", "showFeedbackIcon": true, "scripts": {}, "answerSimplification": "all", "expectedVariableNames": [], "showPreview": true, "checkingAccuracy": 0.001, "variableReplacementStrategy": "originalfirst", "variableReplacements": [], "marks": 1}], "type": "gapfill", "variableReplacementStrategy": "originalfirst", "variableReplacements": [], "marks": 0, "showFeedbackIcon": true}, {"showCorrectAnswer": true, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "prompt": "

Input diagram goes here

\n

Drag the objective line on the diagram above to find the position which gives the maximum profit.

\n

Round your answers down to the nearest integer, end enter them below:

\n

Produce [[0]] {product_1s} and [[1]] {product_2s}, earning £ [[2]] in profit.

", "unitTests": [], "sortAnswers": false, "scripts": {}, "gaps": [{"correctAnswerFraction": false, "allowFractions": false, "customMarkingAlgorithm": "", "mustBeReduced": false, "extendBaseMarkingAlgorithm": true, "minValue": "best_x", "maxValue": "best_x", "unitTests": [], "correctAnswerStyle": "plain", "showFeedbackIcon": true, "scripts": {}, "notationStyles": ["plain", "en", "si-en"], "type": "numberentry", "variableReplacementStrategy": "alwaysreplace", "showCorrectAnswer": true, "variableReplacements": [{"part": "p0g0", "must_go_first": true, "variable": "xconstraint"}, {"part": "p0g1", "must_go_first": true, "variable": "yconstraint"}, {"part": "p1g0", "must_go_first": true, "variable": "resource1x"}, {"part": "p1g1", "must_go_first": true, "variable": "resource1y"}, {"part": "p1g2", "must_go_first": true, "variable": "totalresource1"}, {"part": "p1g3", "must_go_first": true, "variable": "resource2x"}, {"part": "p1g4", "must_go_first": true, "variable": "resource2y"}, {"part": "p1g5", "must_go_first": true, "variable": "totalresource2"}], "marks": 1, "mustBeReducedPC": 0}, {"correctAnswerFraction": false, "allowFractions": false, "customMarkingAlgorithm": "", "mustBeReduced": false, "extendBaseMarkingAlgorithm": true, "minValue": "best_y", "maxValue": "best_y", "unitTests": [], "correctAnswerStyle": "plain", "showFeedbackIcon": true, "scripts": {}, "notationStyles": ["plain", "en", "si-en"], "type": "numberentry", "variableReplacementStrategy": "alwaysreplace", "showCorrectAnswer": true, "variableReplacements": [{"part": "p0g0", "must_go_first": true, "variable": "xconstraint"}, {"part": "p0g1", "must_go_first": true, "variable": "yconstraint"}, {"part": "p1g0", "must_go_first": true, "variable": "resource1x"}, {"part": "p1g1", "must_go_first": true, "variable": "resource1y"}, {"part": "p1g2", "must_go_first": true, "variable": "totalresource1"}, {"part": "p1g3", "must_go_first": true, "variable": "resource2x"}, {"part": "p1g4", "must_go_first": true, "variable": "resource2y"}, {"part": "p1g5", "must_go_first": true, "variable": "totalresource2"}], "marks": 1, "mustBeReducedPC": 0}, {"correctAnswerFraction": false, "allowFractions": false, "customMarkingAlgorithm": "", "mustBeReduced": false, "extendBaseMarkingAlgorithm": true, "minValue": "best_profit", "maxValue": "best_profit", "unitTests": [], "correctAnswerStyle": "plain", "showFeedbackIcon": true, "scripts": {}, "notationStyles": ["plain", "en", "si-en"], "type": "numberentry", "variableReplacementStrategy": "originalfirst", "showCorrectAnswer": true, "variableReplacements": [{"part": "p3g0", "must_go_first": false, "variable": "best_x"}, {"part": "p3g1", "must_go_first": false, "variable": "best_y"}], "marks": 1, "mustBeReducedPC": 0}], "type": "gapfill", "variableReplacementStrategy": "originalfirst", "variableReplacements": [], "marks": 0, "showFeedbackIcon": true}], "variables": {"resource_1_units": {"templateType": "string", "group": "Text strings", "definition": "\"kg\"", "name": "resource_1_units", "description": "

Dimension of the first resource

"}, "resource1y": {"templateType": "anything", "group": "Constraints", "definition": "random(50..70)", "name": "resource1y", "description": "

How much of resource 1 the second product uses per unit

"}, "product_1": {"templateType": "string", "group": "Text strings", "definition": "\"bulletproof tea cosy\"", "name": "product_1", "description": "

Singular name of the first product

"}, "resource2x": {"templateType": "anything", "group": "Constraints", "definition": "\nrandom(250..450#10)", "name": "resource2x", "description": "

How much of resource 2 the first product uses per unit

"}, "business_long": {"templateType": "string", "group": "Text strings", "definition": "\"Amalgamated Mines and Sheep, Inc.\"", "name": "business_long", "description": "

The full name of the business

"}, "profits": {"templateType": "anything", "group": "Optimum strategy", "definition": "map(let(x,p[0],y,p[1],profitx*x+profity*y),p,intersection_points)", "name": "profits", "description": "

Profit earned at each intersection point

"}, "best_profit": {"templateType": "anything", "group": "Optimum strategy", "definition": "profit(best_x,best_y)", "name": "best_profit", "description": "

The profit at the best intersection point

"}, "product_2": {"templateType": "string", "group": "Text strings", "definition": "\"double-edged cardigan\"", "name": "product_2", "description": "

Singular name of the second product

"}, "constraint2xvalue": {"templateType": "anything", "group": "Bounds", "definition": "round(scalingfactor2*resource2y+xconstraint)", "name": "constraint2xvalue", "description": "

Where the constraint line for resource 2 cuts the y-constraint

"}, "r1": {"templateType": "anything", "group": "Constraints", "definition": "random(10..20)", "name": "r1", "description": "

The second constraint line cuts the x-constraint line at this value more than the y-constraint

"}, "constraint1yvalue": {"templateType": "anything", "group": "Bounds", "definition": "r2+constraint2yvalue", "name": "constraint1yvalue", "description": "

Where line given by resource 1 constraint cuts the x-constraint line.

\n

It is always greater than the point at which the second resource line cuts.

"}, "totalresource1": {"templateType": "anything", "group": "Constraints", "definition": "siground(\n scalingfactor1*resource1x*resource1y +\n resource1y*yconstraint +\n resource1x*xconstraint\n,3)", "name": "totalresource1", "description": "

Total amount of resource 1 available

"}, "business_short": {"templateType": "string", "group": "Text strings", "definition": "\"AMS\"", "name": "business_short", "description": "

A shorter name for the business, to be repeated throughout the text. If the business name is short enough for repeated use, leave this empty.

"}, "resource_2": {"templateType": "string", "group": "Text strings", "definition": "\"iron\"", "name": "resource_2", "description": "

The name of the second resource

"}, "best_x": {"templateType": "anything", "group": "Optimum strategy", "definition": "floor(best_x_float)", "name": "best_x", "description": "

The integer number of units of the first product to produce to earn the highest profit

"}, "intersection_points": {"templateType": "anything", "group": "Optimum strategy", "definition": "[\n [xconstraint, (totalresource1-resource1x*xconstraint)/resource1y], //resource 1 intersecting with minimum x\n [xconstraint, (totalresource2-resource2x*xconstraint)/resource2y], //resource 2 intersecting with minimum x\n [(totalresource1-resource1y*yconstraint)/resource1x, yconstraint], //resource 1 intersecting with minimum y\n [(totalresource2-resource2y*yconstraint)/resource2x, yconstraint], //resource 2 intersecting with minimum y\n let(y, (totalresource1-totalresource2*resource1x/resource2x)/(resource1y - resource1x/resource2x * resource2y),\n [(totalresource1-resource1y*y)/resource1x, y] // intersection of the two resource constraints\n )\n]", "name": "intersection_points", "description": "

Intersection points of the constraints - the optimum strategy will be one of these

"}, "business": {"templateType": "anything", "group": "Text strings", "definition": "if(business_short=\"\",business_long,business_short)", "name": "business", "description": ""}, "boundy": {"templateType": "anything", "group": "Bounds", "definition": "max(constraint1yvalue,constraint2yvalue)", "name": "boundy", "description": "

Upper bound of the diagram

"}, "product_2s": {"templateType": "string", "group": "Text strings", "definition": "\"double-edged cardigans\"", "name": "product_2s", "description": "

Plural name of the second product

"}, "constraint1xvalue": {"templateType": "anything", "group": "Bounds", "definition": "round(scalingfactor1*resource1y+xconstraint)", "name": "constraint1xvalue", "description": "

Where the constraint line for resource 1 crosses the y-constraint

"}, "product_1s": {"templateType": "string", "group": "Text strings", "definition": "\"bulletproof tea cosies\"", "name": "product_1s", "description": "

Plural name of the first product

"}, "xconstraint": {"templateType": "anything", "group": "Constraints", "definition": "\nrandom(4..10)", "name": "xconstraint", "description": "

Minimum production of the first product

"}, "profitx": {"templateType": "anything", "group": "Profit", "definition": "//the coeff of x in the objective function\nrandom(2..4)", "name": "profitx", "description": "

Profit for each unit of the first product sold

"}, "best_y_float": {"templateType": "anything", "group": "Optimum strategy", "definition": "intersection_points[best_point][1]", "name": "best_y_float", "description": "

The number of units of the second product to produce to earn the highest profit, if fractions are allowed

"}, "possible_points": {"templateType": "anything", "group": "Optimum strategy", "definition": "filter(\n let(x,floor(intersection_points[j][0]),y,floor(intersection_points[j][1]),\n resource1x*x+resource1y*y <= totalresource1+1 and \n resource2x*x+resource2y*y <= totalresource2+1 and\n x>=xconstraint and\n y>=yconstraint\n ),\n j,\n 0..len(intersection_points)-1\n)", "name": "possible_points", "description": "

Indices of intersection points which satisfy all the constraints.

"}, "line_names": {"templateType": "list of strings", "group": "Optimum strategy", "definition": "[ \"the amount of resource 1 used\", \"the amount of resource 2 used\", \"the minimum amount of X produced\", \"the maximum amount of Y produced\" ]", "name": "line_names", "description": "

Names of the lines, coded as in the definition of best_lines

"}, "resource1x": {"templateType": "anything", "group": "Constraints", "definition": "random(20..40)", "name": "resource1x", "description": "

How much of resource 1 the first product uses per unit

"}, "yconstraint": {"templateType": "anything", "group": "Constraints", "definition": "random(4..10)", "name": "yconstraint", "description": "

Minimum production of the second product

"}, "best_y": {"templateType": "anything", "group": "Optimum strategy", "definition": "floor(best_y_float)", "name": "best_y", "description": "

The integer number of units of the second product to produce to earn the highest profit

"}, "resource_1": {"templateType": "string", "group": "Text strings", "definition": "\"wool\"", "name": "resource_1", "description": "

The name of the first resource

"}, "resource2y": {"templateType": "anything", "group": "Constraints", "definition": "\nrandom(1500..3000#100)", "name": "resource2y", "description": "

How much of resource 2 the second product uses per unit

"}, "totalresource2": {"templateType": "anything", "group": "Constraints", "definition": "siground(\n scalingfactor2*resource2x*resource2y +\n resource2y*yconstraint +\n resource2x*xconstraint\n,3)", "name": "totalresource2", "description": "

Total amount of resource 2 available

"}, "scalingfactor1": {"templateType": "anything", "group": "Constraints", "definition": "precround((r1+r2)/resource1x,1)", "name": "scalingfactor1", "description": ""}, "best_x_float": {"templateType": "anything", "group": "Optimum strategy", "definition": "intersection_points[best_point][0]", "name": "best_x_float", "description": "

The number of units of X to produce to earn the highest profit, if fractions are allowed

"}, "best_profit_float": {"templateType": "anything", "group": "Optimum strategy", "definition": "profit(best_x_float,best_y_float)", "name": "best_profit_float", "description": "

The profit at the best intersection point, if fractions of units are allowed

"}, "profity": {"templateType": "anything", "group": "Profit", "definition": "//the coeff of y in the objective function\nceil(profitx*(resource1y/resource1x)*random(1.5..3))", "name": "profity", "description": "

Profit for each unit of the second product sold

"}, "scalingfactor2": {"templateType": "anything", "group": "Constraints", "definition": "precround((r1)/resource2x,2)", "name": "scalingfactor2", "description": ""}, "r2": {"templateType": "anything", "group": "Constraints", "definition": "random(5..15)", "name": "r2", "description": "

The first constraint line cuts the x-constraint line at this value greater than where the second constraint cuts.

"}, "best_point": {"templateType": "anything", "group": "Optimum strategy", "definition": "best_by(possible_points,profits)", "name": "best_point", "description": "

The index of the valid intersection point with the highest profit

"}, "boundx": {"templateType": "anything", "group": "Bounds", "definition": "max(constraint1xvalue,constraint2xvalue)", "name": "boundx", "description": "

Right bound of the diagram

"}, "best_lines": {"templateType": "anything", "group": "Optimum strategy", "definition": "[[0,2],[1,2],[0,3],[1,3],[0,1]][best_point]", "name": "best_lines", "description": "

Which lines are involed in the best point? Coded as follows:

\n

0 - resource 1

\n

1 - resource 2

\n

2 - minimum x

\n

3 - minimum y

\n

Note that (minimum x,minimum y) is never the best point

"}, "constraint2yvalue": {"templateType": "anything", "group": "Bounds", "definition": "r1+yconstraint", "name": "constraint2yvalue", "description": "

Where the constraint line for the second resource cuts the x-constraint.

\n

Second resource line cuts x-constraint at a point greater than the y-constraint

"}, "resource_2_units": {"templateType": "string", "group": "Text strings", "definition": "\"tonnes\"", "name": "resource_2_units", "description": "

Dimension of the second resource

"}}, "ungrouped_variables": [], "variable_groups": [{"variables": ["xconstraint", "yconstraint", "resource1x", "resource1y", "resource2x", "resource2y", "r1", "r2", "scalingfactor1", "scalingfactor2", "totalresource1", "totalresource2"], "name": "Constraints"}, {"variables": ["boundx", "boundy", "constraint1xvalue", "constraint1yvalue", "constraint2xvalue", "constraint2yvalue"], "name": "Bounds"}, {"variables": ["profitx", "profity"], "name": "Profit"}, {"variables": ["intersection_points", "possible_points", "profits", "best_point", "best_x_float", "best_y_float", "best_profit_float", "best_x", "best_y", "best_profit", "best_lines", "line_names"], "name": "Optimum strategy"}, {"variables": ["business_long", "business_short", "business", "resource_1", "resource_1_units", "resource_2", "resource_2_units", "product_1", "product_1s", "product_2", "product_2s"], "name": "Text strings"}], "functions": {"profit": {"type": "number", "language": "jme", "definition": "profitx*x+profity*y", "parameters": [["x", "number"], ["y", "number"]]}, "best_by": {"type": "number", "language": "javascript", "definition": "// l1 is a list of indices on l2\n// return the element of l1 which has the biggest corresponding value in l2 \n// (i.e. i such that l2[l1[i]] is biggest)\n\nvar best_1 = null;\nvar best_2 = null;\nfor(var i=0;ibest_2) {\n best_2 = l2[l1[i]];\n best_1 = l1[i];\n }\n}\nreturn best_1", "parameters": [["l1", "list"], ["l2", "list"]]}}, "variablesTest": {"condition": "", "maxRuns": 100}, "statement": "

{business_long} ({business_short}) makes two products: {product_1s} and {product_2s}.

\n

Existing orders require {business} to make at least {xconstraint} {product_1s} and {yconstraint} {product_2s} each day.

\n

Each unit of {product_1s} produced uses {resource1x} {resource_1_units} {resource_1} and {resource2x} {resource_2_units} {resource_2}.

\n

Each unit of {product_2s} produced uses {resource1y} {resource_1_units} {resource_1} and {resource2y} {resource_2_units} {resource_2}.

\n

However, the resources are limited: {business} can only obtain {totalresource1} {resource_1_units} {resource_1} and {totalresource2} {resource_2_units} {resource_2} each day.

\n

Each sale of a unit of {product_1s} gives £{profitx} profit. Each sale of a unit of {product_2s} gives £{profity} profit.

", "tags": ["constraints", "linear programming", "objective function", "template"], "rulesets": {}, "preamble": {"css": "", "js": "function userinput_diagram() {\n\nwith(question.unwrappedVariables) {\n\n var options = {\n x_bound: boundx, \n y_bound: boundy\n };\n\n options.objective_line_coordinates = [[0,0],[1,-profitx/profity]];\n \n function getStudentAnswer(path) {\n var part = question.getPart(path);\n return ko.computed(function() {\n return parseFloat(part.display.studentAnswer());\n });\n }\n \n options.minimum_x = getStudentAnswer('p0g0');\n options.minimum_y = getStudentAnswer('p0g1');\n\n var x_coefficient_1 = getStudentAnswer('p1g0');\n var y_coefficient_1 = getStudentAnswer('p1g1');\n var total_1 = getStudentAnswer('p1g2');\n options.inequality_1_coordinates = [ko.computed(function() {\n return [-total_1(),x_coefficient_1(),y_coefficient_1()];\n })];\n\n options.inequality_1_ok = ko.computed(function() {\n return !(isNaN(x_coefficient_1()) || isNaN(y_coefficient_1()) || isNaN(total_1()));\n });\n\n var x_coefficient_2 = getStudentAnswer('p1g3');\n var y_coefficient_2 = getStudentAnswer('p1g4');\n var total_2 = getStudentAnswer('p1g5');\n options.inequality_2_coordinates = [ko.computed(function() {\n return [-total_2(),x_coefficient_2(),y_coefficient_2()];\n })];\n\n options.inequality_2_ok = ko.computed(function() {\n return !(isNaN(x_coefficient_2()) || isNaN(y_coefficient_2()) || isNaN(total_2()));\n });\n\n var result = Numbas.extensions.optimisation.linear_programming_board(options);\n $(question.display.html).find('.lp-graph').html('').append(result.div);\n}\n}\n\nfunction advice_diagram() {\nwith(question.unwrappedVariables) {\n\n var result = Numbas.extensions.optimisation.linear_programming_board({\n x_bound: boundx,\n y_bound: boundy,\n objective_line_coordinates: [[0,best_profit_float/profity],[1,(best_profit_float-profitx)/profity]],\n minimum_x: xconstraint,\n minimum_y: yconstraint,\n inequality_1_coordinates: [-totalresource1, resource1x, resource1y],\n inequality_2_coordinates: [-totalresource2, resource2x, resource2y]\n });\n $(question.display.html).find('#advicediagram').html('').append(result.div);\n}\n}\n\nquestion.signals.on('HTMLAttached',function() {\n userinput_diagram();\n advice_diagram();\n});\n"}, "type": "question", "metadata": {"licence": "Creative Commons Attribution 4.0 International", "description": "

Student is given a set of constraints for a linear program. Asked to enter the constraints as inequalities, and then to identify the optimal solution.

\n

Problem with solving the simultaneous equations gven by the constraints - too unwieldy and not given enough marks for doing so. Best if the point of intersection is given graphically by putting the mouse over the intersection.

"}, "advice": "

a)

\n

The existing orders give two constraints:

\n

\\begin{align}
x &\\geq \\var{xconstraint} \\\\
y &\\geq \\var{yconstraint}
\\end{align}

\n

b)

\n

The limits on the two resources, and the amounts of each resource used to produce a unit of each product, give two further constraints:

\n

\\begin{align}
\\simplify{{resource1x}x + {resource1y}y} &\\leq \\var{totalresource1} \\\\
\\simplify{{resource2x}x + {resource2y}y} &\\leq \\var{totalresource2}
\\end{align}

\n

c)

\n

The objective function to be maximised is the total profit earned, that is, the sum of the profits earned from each unit made:

\n

\\[ \\simplify{{profitx}x + {profity}y} \\]

\n

d)

\n

The solution graph goes here

\n

It is clear that the minimum profit is given by producing enough {product_1s} and {product_2s} so that the existing demand is met and no more. You can see this by moving the objective function line down to the intersection of the two minimum constraint lines - there are no other points inside the feasible region under the objective line.

\n

Next, drag the objective function line upwards until there are no points above the objective line in the feasible region. At this point, the objective line touches the intersection of the lines representing the constraints for {line_names[best_lines[0]]} and {line_names[best_lines[1]]}.

\n

You can find the coordinates of this point by solving the equations for these two lines:

\n

\\[ \\simplify{{resource1x}x + {resource1y}y = {totalresource1}} \\]\\[ \\simplify{{resource2x}x + {resource2y}y = {totalresource2}} \\]

\n

\\[ \\simplify{{resource2x}x + {resource2y}y = {totalresource2}} \\]\\[ x = \\var{xconstraint} \\]\\[ y = \\var{yconstraint} \\]

\n

The solution to this system of equations is $x = \\var{best_x}$, $y = \\var{best_y}$, giving a profit of

\n

\\[ \\text{Profit} = \\simplify[]{{profitx}*{best_x} + {profity}*{best_y}} = \\text{£}\\var{best_profit} \\]

"}], "name": "", "pickQuestions": 0}], "metadata": {"notes": "", "licence": "Creative Commons Attribution 4.0 International", "description": "

Solve a linear programming problem, and perform sensitivity analysis.

"}, "type": "exam", "navigation": {"onleave": {"action": "none", "message": ""}, "reverse": true, "browse": true, "showresultspage": "oncompletion", "preventleave": true, "allowregen": true, "showfrontpage": true}, "timing": {"timedwarning": {"action": "none", "message": ""}, "timeout": {"action": "none", "message": ""}, "allowPause": true}, "pickQuestions": 0, "contributors": [{"name": "Newcastle University Mathematics and Statistics", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/697/"}], "extensions": ["jsxgraph", "optimisation"], "custom_part_types": [], "resources": []}