// Numbas version: exam_results_page_options {"name": "Denis's copy of mathcentre: Linear Programming (Business)", "question_groups": [{"pickingStrategy": "all-ordered", "name": "", "questions": [{"name": "Linear Programming 6", "extensions": ["jsxgraph"], "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/"}], "functions": {"diagram": {"definition": "var solpt;\nvar solx;\nvar soly;\nvar Pfunction=function(x,y){return xprofit*x+yprofit*y;};\nvar pt;\nvar xboundR=(resource*1000-Yresource*(yconstraint))/Xresource+5;\nvar xboundT=(timeavailable*60-Ytime*(yconstraint))/Xtime+5;\nvar yboundR=(resource*1000-Xresource*(xconstraint))/Yresource+5;\nvar yboundT=(timeavailable*60-Xtime*(xconstraint))/Ytime+5;\nvar xbound=Math.max(xboundR,xboundT,yboundR,yboundT);\nvar ybound=xbound;\nvar div = Numbas.extensions.jsxgraph.makeBoard('400px','400px',{\n boundingBox:[-20,ybound,xbound,-20],\n axis:true,\n showNavigation:false,\n grid:false\n});\nvar board=div.board;\n\n//Create lines using homogeneous coordinates - beware,ax+by+c=0\n//is entered as [c,a,b]\nvar lineR=board.create('line',[-resource*1000,Xresource,Yresource],{name:'Cocoa',withLabel:true,fixed:true});\nvar lineT=board.create('line',[-60*timeavailable,Xtime,Ytime],{name:'Time',withLabel:true,fixed:true});\nvar ep=board.create('intersection',[lineR,lineT],{name:'T',withLabel:true,face:'x',fixed:true});\n\nvar xconst=board.create('line',[[xconstraint,0],[xconstraint,ybound]],{strokeColor:'red',fixed:true});\nvar yconst=board.create('line',[[0,yconstraint],[xbound,yconstraint]],{strokeColor:'red',fixed:true});\n\nvar al=board.create('point',[xconstraint,yconstraint],{name:'',face:'x',fixed:true});\nvar be;\nvar ga;\nvar te=((resource*1000-Yresource*yconstraint)/Xresource>(timeavailable*60-Ytime*yconstraint)/Xtime);\nvar te1=((resource*1000-Xresource*xconstraint)/Yresource>(timeavailable*60-Xtime*xconstraint)/Ytime);\nif(!te)\n {be=board.create('point',[(resource*1000-Yresource*yconstraint)/Xresource,yconstraint],{name:'Q',face:'x',fixed:true});}\nelse \n {be=board.create('point',[(timeavailable*60-Ytime*yconstraint)/Xtime,yconstraint],{name:'Q',face:'x',fixed:true});}\nif(!te1)\n{ga=board.create('point',[xconstraint,(resource*1000-Xresource*xconstraint)/Yresource],{name:'R',face:'x',fixed:true});}\nelse\n {ga=board.create('point',[xconstraint,(timeavailable*60-Xtime*xconstraint)/Ytime],{name:'R',face:'x',fixed:true});}\n\nif((!te&& te1)||(te&&!te1)){\n board.create('polygon',[al,be,ep,ga],{name:\"Feasible Region\",withLabel:false});\n if(Pfunction(ep.X(),ep.Y())>Math.max(Pfunction(ga.X(),ga.Y()),Pfunction(be.X(),be.Y())))\n{solx=ep.X();soly=ep.Y();pt='T';}\n else {\n if(Pfunction(be.X(),be.Y())>Pfunction(ga.X(),ga.Y()))\n {solx=be.X();soly=be.Y();pt='Q';}\n \n else \n {solx=ga.X();soly=ga.Y();pt='R';}\n }\n}\n \n else{\n board.create('polygon',[al,be,ga],{name:\"Feasible Region\",withLabel:false});\n \n if(Pfunction(be.X(),be.Y())>Pfunction(ga.X(),ga.Y()))\n{solx=be.X();soly=be.Y();pt='Q';}\n else \n{solx=ga.X();soly=ga.Y();pt='R';}\n }\n \n\nvar solx=Numbas.math.precround(Numbas.math.niceNumber(solx),1);\nvar soly=Numbas.math.precround(Numbas.math.niceNumber(soly),1);\nvar P=board.create('slider',[[xbound-50, ybound-10], [xbound-50,ybound-60], [0, Pfunction(solx,soly)/100, 100]],{name:'Profit'});\nvar PL=board.create('line',[[function(){return 100*P.Value()/(xprofit);},0],[0,function(){return 100*P.Value()/(yprofit);}]],{strokeColor:'green',dash:1,name:'Profit',withLabel:true});\nvar t1 = board.create('text',[xbound-300,ybound-200,\"solutions:x= \"+solx+\",y= \"+soly]);\nvar html = $(question.display.html);\nhtml.find('#xsol').text(solx);\nhtml.find('#ysol').text(soly);\nhtml.find('#ptname').text(pt);\nreturn div;\n", "type": "html", "language": "javascript", "parameters": [["Xresource", "number"], ["Yresource", "number"], ["Xtime", "number"], ["Ytime", "number"], ["xconstraint", "number"], ["yconstraint", "number"], ["resource", "number"], ["timeavailable", "number"], ["xprofit", "number"], ["yprofit", "number"]]}, "userinput": {"definition": "var xboundR=(resource*1000-Yresource*(yconstraint))/Xresource+5;\nvar xboundT=(timeavailable*60-Ytime*(yconstraint))/Xtime+5;\nvar yboundR=(resource*1000-Xresource*(xconstraint))/Yresource+5;\nvar yboundT=(timeavailable*60-Xtime*(xconstraint))/Ytime+5;\nvar xbound=Math.max(xboundR,xboundT,yboundR,yboundT);\nvar ybound=xbound;\nvar profitondemand=(xconstraint*xprofit+yconstraint*yprofit)/100\nvar div = Numbas.extensions.jsxgraph.makeBoard('400px','400px',{\n boundingBox:[-20,ybound,xbound,-20],\n axis:true,\n showNavigation:false,\n grid:false\n});\nvar board=div.board;\nvar P=board.create('slider',[[xbound-50, ybound-10], [xbound-50,ybound-60], [0, profitondemand, 100]],{name:'Profit'});\nvar PL=board.create('line',[[function(){return 100*P.Value()/(xprofit);},0],[0,function(){return 100*P.Value()/(yprofit);}]],{strokeColor:'green',dash:1,name:'Profit',withLabel:true});\nquestion.signals.on('HTMLAttached',function(e) {\n \n //set up KO observables to compute the coordinates from the student's input\n var xcon = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[0].display.studentAnswer());\n });\n var ycon = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[1].display.studentAnswer());\n });\n var aa = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[2].display.studentAnswer());\n });\n var ba = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[3].display.studentAnswer());\n });\n var ca = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[4].display.studentAnswer());\n });\n var ta_coordinates = ko.computed(function() {\nif(isNaN(aa()) || isNaN(ba()) || isNaN(ca())) {\n // return [0,0,1];\n}\nreturn [-ca(),aa(),ba()];\n });\n \n // create the lines\n var x_constraint_line = board.create('line',[[xcon,0],[xcon,1]],{strokeColor:'red',fixed:true, straightFirst: false});\n var y_constraint_line = board.create('line',[[0,ycon],[1,ycon]],{strokeColor:'red',fixed:true, straightFirst: false});;\nvar inequality_linea = board.create('line',[ta_coordinates],{name:'Cocoa',withLabel:true});\n var ab = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[5].display.studentAnswer());\n });\n var bb = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[6].display.studentAnswer());\n });\n var cb = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[7].display.studentAnswer());\n });\n var tb_coordinates = ko.computed(function() {\nif(isNaN(ab()) || isNaN(bb()) || isNaN(cb())) {\n // return [0,0,1];\n}\nreturn [-cb(),ab(),bb()];\n });\n \n var inequality_lineb = board.create('line',[tb_coordinates],{name:'Time',withLabel:true});\n var ep=board.create('intersection',[inequality_linea,inequality_lineb],{name:'T',face:'x',visible:false});\n var al=board.create('point',[xcon,ycon],{name:'P',face:'x',fixed:true});\n var be1=board.create('intersection',[inequality_linea,y_constraint_line],{name:'Q',face:'x',fixed:true,visible:false});\n var be2=board.create('intersection',[inequality_lineb,y_constraint_line],{name:'Q',face:'x',fixed:true,visible:false});\n var ga=board.create('intersection',[x_constraint_line,inequality_linea],{name:'R',face:'x',fixed:true,visible:false});\n var del=board.create('intersection',[x_constraint_line,inequality_lineb],{name:'R',face:'x',fixed:true,visible:false});\n var fr1=board.create('polygon',[al,be2,ep,ga],{name:\"Feasible Region\",visible:false}); \n var fr2=board.create('polygon',[al,be1,ga],{name:\"Feasible Region\",visible:false}); \n var fr3=board.create('polygon',[al,be2,del],{name:\"Feasible Region\",visible:false}); \n var fr4=board.create('polygon',[al,be1,ep,del],{name:\"Feasible Region\",visible:false}); \n ko.computed(function(){ \n// look at the observables, so this function gets called whenever they change\nxcon(),ycon(),ta_coordinates(),tb_coordinates();\n\nvar lineAOK=!(isNaN(aa()) || isNaN(ba()) || isNaN(ca()));\nvar lineBOK=!(isNaN(ab()) || isNaN(bb()) || isNaN(cb()));\nvar consxOK= !isNaN(xcon());var consyOK= !isNaN(ycon());\n// show/hide the lines based on whether the student input is valid\nvar te=(be1.X()> be2.X());\nvar te1=(ga.Y()> del.Y());\nx_constraint_line.setAttribute({'visible':consxOK});\ny_constraint_line.setAttribute({'visible': consyOK}); \ninequality_linea.setAttribute({'visible': lineAOK});\ninequality_lineb.setAttribute({'visible': lineBOK});\nal.setAttribute({'visible':consxOK&&consyOK});\nep.setAttribute({'visible':((lineAOK&&lineBOK))&&((!te&&te1)||(te&&!te1))});\nbe1.setAttribute({'visible':lineAOK&&!te});\nbe2.setAttribute({'visible':lineBOK&&(te)});\nga.setAttribute({'visible':(lineAOK&&consxOK)&&!te1});\ndel.setAttribute({'visible':(lineBOK&&consxOK)&&(te1)}); \nvar fr1_visible = ((consxOK&&consyOK)&&(lineAOK&&lineBOK))&&((te)&&!te1);\nvar fr2_visible = consxOK&&consyOK&&lineAOK&&lineBOK&&!te&&!te1;\nvar fr3_visible = consxOK&&consyOK&&lineAOK&&lineBOK&&(te)&&(te1);\nvar fr4_visible = (consxOK&&consyOK)&&(lineAOK&&lineBOK)&&(!te)&&(te1);\nfr1.setAttribute({'visible':fr1_visible, 'fillOpacity': fr1_visible ? 0.3 : 0});\nfr2.setAttribute({'visible':fr2_visible, 'fillOpacity': fr2_visible ? 0.3 : 0}); \nfr3.setAttribute({'visible':fr3_visible, 'fillOpacity': fr3_visible ? 0.3 : 0}); \nfr4.setAttribute({'visible':fr4_visible, 'fillOpacity': fr4_visible ? 0.3 : 0}); \n// prompt JSXGraph to reevaluate the coordinate functions\nboard.update(); \n }); \n});\n\nreturn div;\n", "type": "html", "language": "javascript", "parameters": [["Xresource", "number"], ["Yresource", "number"], ["Xtime", "number"], ["Ytime", "number"], ["xconstraint", "number"], ["yconstraint", "number"], ["resource", "number"], ["timeavailable", "number"], ["xprofit", "number"], ["yprofit", "number"]]}}, "tags": ["Feasible region", "Jsxgraph", "constraints", "graphical method", "jsxgraph", "linear programming", "maximise", "objective function"], "type": "question", "advice": "

{diagram(xresource,yresource,xtime,ytime,xconstraint,yconstraint,resource,timeavailable,xprofit,yprofit)}

\n

It is clear that the minimum profit is given by producing enough toys so that demand is met and no more. You can see this by moving the slider so that the objective function line goes through the point giving the demand. Note that this is given in the diagram in the statement of the question.

\n

Solving the pair of equations given by the lines which intersect at point we find that a solution for maximum profit is:

\n

Number of Bears to be produced, $x=\\;$  (to one decimal place).

\n

Number of Cats to be produced, $y=\\;$  (to one decimal place).

\n

If these are not whole numbers, then you will have to adjust them accordingly to get realistic solutions.

\n

", "rulesets": {}, "parts": [{"showcorrectanswer": true, "prompt": "

Let $x,\\;y$ be the number of units of Asteroids, Blackholes produced respectively.

\n

{userinput(xresource,yresource,xtime,ytime,xconstraint,yconstraint,resource,timeavailable,xprofit,yprofit)}

\n

What are the constraints on production.?

\n

$x \\ge\\;$[[0]]      $y \\ge\\;$[[1]]

\n

Now input the constraints given by availability of cocoa and time:

\n

Cocoa: [[2]]$x\\;+\\;$[[3]]$y\\;\\le\\;$[[4]]   (in grammes)

\n

Time: [[5]]$x\\;+\\;$[[6]]$y\\;\\le\\;$[[7]]   (in minutes)

\n

Input the objective function which maximises profit.

\n

Objective function :[[8]]

\n

The profit objective function is displayed above as a green dashed line. It is initially set at the profit if demand is just met.

\n

Once you have input all of the constraints you can use the slider to move the objective function to the value of $x$ and $y$ in the Feasible region to maximise profit.

\n

Using this diagram find values of the production of $x$ and $y$ which satisfy the constraints and maximise the profit in a day's production by identifying the equations you need to solve algebraically.

\n

", "gaps": [{"showcorrectanswer": true, "minvalue": "xconstraint", "type": "numberentry", "maxvalue": "xconstraint", "marks": 1.0, "showPrecisionHint": false}, {"showcorrectanswer": true, "minvalue": "yconstraint", "type": "numberentry", "maxvalue": "yconstraint", "marks": 1.0, "showPrecisionHint": false}, {"showcorrectanswer": true, "minvalue": "xresource", "type": "numberentry", "maxvalue": "xresource", "marks": 1.0, "showPrecisionHint": false}, {"showcorrectanswer": true, "minvalue": "yresource", "type": "numberentry", "maxvalue": "yresource", "marks": 1.0, "showPrecisionHint": false}, {"showcorrectanswer": true, "minvalue": "resource*1000", "type": "numberentry", "maxvalue": "resource*1000", "marks": 1.0, "showPrecisionHint": false}, {"showcorrectanswer": true, "minvalue": "xtime", "type": "numberentry", "maxvalue": "xtime", "marks": 1.0, "showPrecisionHint": false}, {"showcorrectanswer": true, "minvalue": "ytime", "type": "numberentry", "maxvalue": "ytime", "marks": 1.0, "showPrecisionHint": false}, {"showcorrectanswer": true, "minvalue": "timeavailable*60", "type": "numberentry", "maxvalue": "timeavailable*60", "marks": 1.0, "showPrecisionHint": false}, {"expectedvariablenames": [], "checkingaccuracy": 0.001, "vsetrange": [0.0, 1.0], "showpreview": true, "vsetrangepoints": 5.0, "showcorrectanswer": true, "answersimplification": "all", "marks": 1.0, "answer": "{xprofit}*x+{yprofit}*y", "checkingtype": "absdiff", "checkvariablenames": false, "type": "jme"}], "type": "gapfill", "marks": 0.0}], "statement": "

A chocolate manufacturer produces two types of chocolate bar: Asteroids and Blackholes.

\n

Production of an Asteroid bar uses {xresource}g of cocoa and {xtime} minute(s) of machine time, whereas a Blackhole bar requires {yresource}g of cocoa and {ytime} minute(s) of machine time.

\n

Altogether, {resource}kg of cocoa are available each day.

\n

The company employs a single machine operator who works on the production of these bars for {timeavailable} hours per day.

\n

The manufacturer must make at least {xconstraint} Asteroid and {yconstraint} Blackholes each day to keep up with demand.

\n

The manufacturer makes {xprofit}p profit from each Asteroid bar and {yprofit}p profit from each Blackhole bar.

\n

(a) Formulate the chocolate manufacturer’s situation as a linear programming  problem and input this information in the fields below.

\n

(b) After this input a suitable diagram will be drawn on screen to enable the problem to be solved graphically, but will give approximate solutions.

\n

(c) Use your diagram to find an approximate value for the company’s minimum and maximum profit, £P.

\n

(d) Using the information given by the diagram, once you have completed all inputs, you can identify and solve the pair of equations in order to find the production that achieves maximum profit. This give a more accurate solution, but you may meed to adjust to obtain whole numbers of products!

", "variable_groups": [], "progress": "in-progress", "preamble": {"css": "", "js": ""}, "variables": {"timeavailable": {"definition": "max(ceil((xtime*xconstraint+ytime*yconstraint +60)/60),random(7..9))\n", "name": "timeavailable"}, "yconstraint": {"definition": "random(30..50#5)\n", "name": "yconstraint"}, "resource": {"definition": "ceil((xresource*xconstraint+yresource*yconstraint+random(500..1000))/1000)", "name": "resource"}, "xprofit": {"definition": "random(8..18)", "name": "xprofit"}, "yprofit": {"definition": "random(10..25 except xprofit)", "name": "yprofit"}, "xconstraint": {"definition": "random(30..60#5)", "name": "xconstraint"}, "ytime": {"definition": "random(1..3#0.5 except xtime)", "name": "ytime"}, "yresource": {"definition": "if(xtime > ytime, xresource+random(1,1.5,2),xresource-random(1,1.5,2))", "name": "yresource"}, "xtime": {"definition": "random(1..3#0.5)", "name": "xtime"}, "xresource": {"definition": "random(5..10#0.5)", "name": "xresource"}}, "metadata": {"notes": "

30/01/2014:

\n

First version finished. Algebraic solution of equations to be added.

\n

Display needs improving. Repositioning of text to be done.

", "description": "

Linear program to find maximum profit using an objective function from the manufacture of two items with constraints on time and materials.

\n

This assumes that there are constraints on the number of items produced i.e. there is a mininum number of each.

", "licence": "Creative Commons Attribution 4.0 International"}, "showQuestionGroupNames": false, "question_groups": [{"name": "", "pickingStrategy": "all-ordered", "pickQuestions": 0, "questions": []}]}, {"name": "Stephanie's copy of Generic LP 2", "extensions": ["stats", "jsxgraph"], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "contributors": [{"name": "Stephanie Greaves", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/340/"}], "functions": {}, "ungrouped_variables": ["yconstraint", "constraint1xvalue", "r1", "boundx", "boundy", "constraint2yvalue", "scalingfactor1", "scalingfactor2", "resource1y", "resource1x", "xconstraint", "constraint2xvalue", "resource2x", "resource2y", "profity", "profitx", "r2", "constraint1yvalue", "totalresource1", "totalresource2"], "tags": ["LP", "constraints", "generic", "linear programming", "objective function", "programming", "template"], "preamble": {"css": "", "js": "\n// declare variables to be shared between the functions userinput_board and diagram\nvar xconstraint;\nvar yconstraint;\nvar coeff1x;\nvar coeff1y;\nvar coeff2x;\nvar coeff2y;\nvar resource1;\nvar resource2;\nvar boundx;\nvar boundy;\nvar profitx;\nvar profity;\n\n\n// get_variables is called after the randomised variables have been generated\nfunction get_variables() {\n var scope = question.scope;\n coeff1x = Numbas.jme.unwrapValue(scope.variables.resource1x);\n coeff1y = Numbas.jme.unwrapValue(scope.variables.resource1y);\n coeff2x= Numbas.jme.unwrapValue(scope.variables.resource2x);\n coeff2y = Numbas.jme.unwrapValue(scope.variables.resource2y);\n resource1 = Numbas.jme.unwrapValue(scope.variables.totalresource1);\n resource2= Numbas.jme.unwrapValue(scope.variables.totalresource2);\n xconstraint = Numbas.jme.unwrapValue(scope.variables.xconstraint);\n yconstraint = Numbas.jme.unwrapValue(scope.variables.yconstraint);\n boundx = Numbas.jme.unwrapValue(scope.variables.boundx);\n boundy = Numbas.jme.unwrapValue(scope.variables.boundy);\n profitx = Numbas.jme.unwrapValue(scope.variables.profitx);\n profity = Numbas.jme.unwrapValue(scope.variables.profity);\n profitondemand=(xconstraint*profitx+yconstraint*profity);\n constraint1xvalue=Numbas.jme.unwrapValue(scope.variables.constraint1xvalue);\n constraint2xvalue=Numbas.jme.unwrapValue(scope.variables.constraint2xvalue);\n constraint1yvalue=Numbas.jme.unwrapValue(scope.variables.constraint1yvalue);\n constraint2yvalue=Numbas.jme.unwrapValue(scope.variables.constraint2yvalue);\n}\n\n// all the variables declared above can be accessed by any other function\nfunction userinput_board(){\n var div = Numbas.extensions.jsxgraph.makeBoard('400px','400px',{\nboundingBox:[-2,boundy+2,boundx+2,-2],\naxis:true,\nshowNavigation:false,\ngrid:true\n });\n \n $(question.display.html).find('#userinput').html('').append(div);\n var board=div.board;\n var P=board.create('slider',[[boundx-12, boundy-5], [boundx-12,boundy-15], [0, profitondemand, 1000]],{name:'Profit'});\n var PL=board.create('line',[[function(){return P.Value()/(profitx);},0],[0,function(){return P.Value()/(profity);}]],{strokeColor:'green',dash:1,name:'Profit',withLabel:true});\n var xcon = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[0].display.studentAnswer());\n });\n var ycon = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[1].display.studentAnswer());\n });\n var aa = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[2].display.studentAnswer());\n });\n var ba = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[3].display.studentAnswer());\n });\n var ca = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[4].display.studentAnswer());\n });\n var ta_coordinates = ko.computed(function() {\nif(isNaN(aa()) || isNaN(ba()) || isNaN(ca())) {\n // return [0,0,1];\n}\nreturn [-ca(),aa(),ba()];\n });\n \n // create the lines\n var x_constraint_line = board.create('line',[[xcon,0],[xcon,1]],{strokeColor:'red',fixed:true, straightFirst: false});\n var y_constraint_line = board.create('line',[[0,ycon],[1,ycon]],{strokeColor:'red',fixed:true, straightFirst: false});;\n var inequality_linea = board.create('line',[ta_coordinates],{name:'Resource 1',withLabel:true});\n var ab = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[5].display.studentAnswer());\n });\n var bb = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[6].display.studentAnswer());\n });\n var cb = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[7].display.studentAnswer());\n });\n var tb_coordinates = ko.computed(function() {\nif(isNaN(ab()) || isNaN(bb()) || isNaN(cb())) {\n // return [0,0,1];\n}\nreturn [-cb(),ab(),bb()];\n });\n \n var inequality_lineb = board.create('line',[tb_coordinates],{name:'Resource 2',withLabel:true});\n var ep=board.create('intersection',[inequality_linea,inequality_lineb],{name:'I',face:'x',visible:false});\n var al=board.create('point',[xcon,ycon],{name:'P',face:'x',fixed:true});\n var be1=board.create('intersection',[inequality_linea,y_constraint_line],{name:'Q',face:'x',fixed:true,visible:false});\n var be2=board.create('intersection',[inequality_lineb,y_constraint_line],{name:'Q',face:'x',fixed:true,visible:false});\n var ga=board.create('intersection',[x_constraint_line,inequality_linea],{name:'R',face:'x',fixed:true,visible:false});\n var del=board.create('intersection',[x_constraint_line,inequality_lineb],{name:'R',face:'x',fixed:true,visible:false});\n var fr1=board.create('polygon',[al,be2,ep,ga],{name:\"Feasible Region\",visible:false}); \n var fr2=board.create('polygon',[al,be1,ga],{name:\"Feasible Region\",visible:false}); \n var fr3=board.create('polygon',[al,be2,del],{name:\"Feasible Region\",visible:false}); \n var fr4=board.create('polygon',[al,be1,ep,del],{name:\"Feasible Region\",visible:false}); \n ko.computed(function(){ \n// look at the observables, so this function gets called whenever they change\nxcon(),ycon(),ta_coordinates(),tb_coordinates();\n\nvar lineAOK=!(isNaN(aa()) || isNaN(ba()) || isNaN(ca()));\nvar lineBOK=!(isNaN(ab()) || isNaN(bb()) || isNaN(cb()));\nvar consxOK= !isNaN(xcon());var consyOK= !isNaN(ycon());\n// show/hide the lines based on whether the student input is valid\nvar te=(be1.X()> be2.X());\nvar te1=(ga.Y()> del.Y());\nx_constraint_line.setAttribute({'visible':consxOK});\ny_constraint_line.setAttribute({'visible': consyOK}); \ninequality_linea.setAttribute({'visible': lineAOK});\ninequality_lineb.setAttribute({'visible': lineBOK});\nal.setAttribute({'visible':consxOK&&consyOK});\nep.setAttribute({'visible':((lineAOK&&lineBOK))&&((!te&&te1)||(te&&!te1))});\nbe1.setAttribute({'visible':lineAOK&&!te});\nbe2.setAttribute({'visible':lineBOK&&(te)});\nga.setAttribute({'visible':(lineAOK&&consxOK)&&!te1});\ndel.setAttribute({'visible':(lineBOK&&consxOK)&&(te1)}); \nvar fr1_visible = ((consxOK&&consyOK)&&(lineAOK&&lineBOK))&&((te)&&!te1);\nvar fr2_visible = consxOK&&consyOK&&lineAOK&&lineBOK&&!te&&!te1;\nvar fr3_visible = consxOK&&consyOK&&lineAOK&&lineBOK&&(te)&&(te1);\nvar fr4_visible = (consxOK&&consyOK)&&(lineAOK&&lineBOK)&&(!te)&&(te1);\nfr1.setAttribute({'visible':fr1_visible, 'fillOpacity': fr1_visible ? 0.3 : 0});\nfr2.setAttribute({'visible':fr2_visible, 'fillOpacity': fr2_visible ? 0.3 : 0}); \nfr3.setAttribute({'visible':fr3_visible, 'fillOpacity': fr3_visible ? 0.3 : 0}); \nfr4.setAttribute({'visible':fr4_visible, 'fillOpacity': fr4_visible ? 0.3 : 0}); \n// prompt JSXGraph to reevaluate the coordinate functions\nboard.update(); \n }); \n}\nfunction diagram(){\n var solx;\n var soly;\n var Pfunction=function(x,y){return profitx*x+profity*y;};\n var pt;\n var div = Numbas.extensions.jsxgraph.makeBoard('400px','400px',{\nboundingBox:[-2,boundy+2,boundx+2,-4],\naxis:true,\nshowNavigation:false,\ngrid:true\n });\n var board=div.board;\n $(question.display.html).find('#advicediagram').append(div);\n //Create lines using homogeneous coordinates - beware,ax+by+c=0\n //is entered as [c,a,b]\n var liner1=board.create('line',[-resource1,coeff1x,coeff1y],{name:'Resource 1',withLabel:true,fixed:true});\n var liner2=board.create('line',[-resource2,coeff2x,coeff2y],{name:'Resource 2',withLabel:true,fixed:true});\n var ep=board.create('intersection',[liner1,liner2],{name:'I',withLabel:true,face:'x',fixed:true});\n \n var xconst=board.create('line',[[xconstraint,0],[xconstraint,boundy]],{strokeColor:'red',fixed:true});\n var yconst=board.create('line',[[0,yconstraint],[boundx,yconstraint]],{strokeColor:'red',fixed:true});\n var pt1intx=board.create('intersection',[liner1,xconst],{face:'x',fixed:true,name:' '});\n var pt1inty=board.create('intersection',[liner1,yconst],{face:'x',fixed:true,name:' '});\n var pt2intx=board.create('intersection',[liner2,xconst],{face:'x',fixed:true,name:' '});\n var pt2inty=board.create('intersection',[liner2,yconst],{face:'x',fixed:true,name:' '});\n var al=board.create('point',[xconstraint,yconstraint],{name:'P',face:'x',fixed:true});\n var be;\n var ga;\n var te=(pt1inty.X()>pt2inty.X());\n var te1=(pt1intx.Y()>pt2intx.Y());\n if(!te)\n {be=board.create('point',[pt1inty.X(),yconstraint],{name:'Q',face:'x',fixed:true});}\n else \n {be=board.create('point',[pt2inty.X(),yconstraint],{name:'Q',face:'x',fixed:true});}\n if(!te1)\n {ga=board.create('point',[xconstraint,pt1intx.Y()],{name:'R',face:'x',fixed:true});}\n else\n {ga=board.create('point',[xconstraint,pt2intx.Y()],{name:'R',face:'x',fixed:true});}\n \n if((!te&& te1)||(te&&!te1)){\nboard.create('polygon',[al,be,ep,ga],{name:\"Feasible Region\",withLabel:false});\nif(Pfunction(ep.X(),ep.Y())>Math.max(Pfunction(ga.X(),ga.Y()),Pfunction(be.X(),be.Y())))\n {solx=ep.X();soly=ep.Y();pt='I';}\nelse {\n if(Pfunction(be.X(),be.Y())>Pfunction(ga.X(),ga.Y()))\n{solx=be.X();soly=be.Y();pt='Q';}\n \n else \n {solx=ga.X();soly=ga.Y();pt='R';}\n}\n }\n \n else{\nboard.create('polygon',[al,be,ga],{name:\"Feasible Region\",withLabel:false});\n\nif(Pfunction(be.X(),be.Y())>Pfunction(ga.X(),ga.Y()))\n {solx=be.X();soly=be.Y();pt='Q';}\nelse \n{solx=ga.X();soly=ga.Y();pt='R';}\n }\n \n \n var solx=Numbas.math.precround(Numbas.math.niceNumber(solx),1);\n var soly=Numbas.math.precround(Numbas.math.niceNumber(soly),1);\n var P=board.create('slider',[[boundx-10, boundy-5], [boundx-10,boundy-15], [0, Pfunction(solx,soly), 1000]],{name:'Profit'});\n var PL=board.create('line',[[function(){return P.Value()/(profitx);},0],[0,function(){return P.Value()/(profity);}]],{strokeColor:'green',dash:1,name:'Profit',withLabel:true});\n var t1 = board.create('text',[1,-2,\"solutions:x= \"+solx+\",y= \"+soly]);\n var html = $(question.display.html);\n html.find('#xsol').text(solx);\n html.find('#ysol').text(soly);\n html.find('#ptname').text(pt);\n}\n\nquestion.signals.on('HTMLAttached',function() {\n //assign values to the common variables\n get_variables();\n //diagram user draws on in the question.\n userinput_board();\n //solution diagram found in Advice.\n diagram();\n});\n"}, "advice": "

The solution

\n

\n

It is clear that the minimum profit is given by producing enough snapjacks and snaxz so that demand is met and no more. You can see this by moving the slider so that the objective function line goes through the point giving the demand. Note that this is given in the diagram in the statement of the question.

\n

Solving the pair of equations given by the lines which intersect at point we find that a solution for maximum profit is:

\n

Number of snapjacks to be produced, $x=\\;$  (to one decimal place).

\n

Number of snaxz to be produced, $y=\\;$  (to one decimal place).

\n

If these are not whole numbers, then you will have to adjust them accordingly to get realistic solutions.

\n

", "rulesets": {}, "parts": [{"prompt": "

Input diagram

\n

Let $x,\\;y$ be the number of units of snapjacks and snaxz produced respectively.

\n

What are the constraints on production ?

\n

$x \\ge\\;$[[0]]      $y \\ge\\;$[[1]]

\n

Now input the constraints given by availability of porridge oats and cocoa:

\n

Porridge oats: [[2]]$x\\;+\\;$[[3]]$y\\;\\le\\;$[[4]]  

\n

cocoa: [[5]]$x\\;+\\;$[[6]]$y\\;\\le\\;$[[7]]  

\n

Given the information on profits for snapjacks and snaxz input the objective function which is to be maximised: [[8]]

\n

Hence by moving the slider find an approximate value for the maximum profit and also solve the two equations which intersect at the maximum profit point and so find the amounts  of snapjacks and snaxz to be produced to achieve this maximum profit.

", "marks": 0, "gaps": [{"allowFractions": false, "marks": 1, "maxValue": "xconstraint", "minValue": "xconstraint", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "yconstraint", "minValue": "yconstraint", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "resource1x", "minValue": "resource1x", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "resource1y", "minValue": "resource1y", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "totalresource1", "minValue": "totalresource1", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "resource2x", "minValue": "resource2x", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "resource2y", "minValue": "resource2y", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "totalresource2", "minValue": "totalresource2", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"vsetrangepoints": 5, "expectedvariablenames": [], "checkingaccuracy": 0.001, "vsetrange": [0, 1], "showpreview": true, "marks": 1, "showCorrectAnswer": true, "answersimplification": "all", "scripts": {}, "answer": "{profitx}*x+{profity}*y", "checkingtype": "absdiff", "checkvariablenames": false, "type": "jme"}], "showCorrectAnswer": true, "scripts": {}, "type": "gapfill"}], "statement": "

snapjacks and snaxz are two popular products. 

\n

There must be at least {xconstraint} batches of snapjacks and {yconstraint} batches of snaxz produced each day to meet ordered sales.

\n

Each snapjack batch needs {resource1x}g  porridge oats and  {resource2x}g cocoa every day.

\n

Each snaxz batch needs {resource1y}g porridge oats and  {resource2y}g cocoa every day.

\n

However, the resources are limited:  

\n

{totalresource1}g of porridge oats each day.

\n

{totalresource2}g of cocoa each day.

\n

Each sale of a unit of snapjacks gives £{profitx} profit. Each sale of a unit of snaxz gives £{profity} profit.

\n

", "variable_groups": [], "variablesTest": {"maxRuns": 100, "condition": ""}, "variables": {"yconstraint": {"definition": "//least allocation of Y - forced.\nrandom(4..10)", "templateType": "anything", "group": "Ungrouped variables", "name": "yconstraint", "description": ""}, "constraint1xvalue": {"definition": "round(scalingfactor1*resource1y+xconstraint)", "templateType": "anything", "group": "Ungrouped variables", "name": "constraint1xvalue", "description": ""}, "r1": {"definition": "//the second constraint line cuts the xconstraint line at this value more than the yconstraint\nrandom(10..20)", "templateType": "anything", "group": "Ungrouped variables", "name": "r1", "description": ""}, "boundx": {"definition": "max(constraint1xvalue,constraint2xvalue)", "templateType": "anything", "group": "Ungrouped variables", "name": "boundx", "description": ""}, "boundy": {"definition": "max(constraint1yvalue,constraint2yvalue)", "templateType": "anything", "group": "Ungrouped variables", "name": "boundy", "description": ""}, "constraint2yvalue": {"definition": "//second resource line cuts x=xconstraint at a point greater than the yconstraint\nr1+yconstraint", "templateType": "anything", "group": "Ungrouped variables", "name": "constraint2yvalue", "description": ""}, "scalingfactor1": {"definition": "precround((r1+r2)/resource1x,1)", "templateType": "anything", "group": "Ungrouped variables", "name": "scalingfactor1", "description": ""}, "scalingfactor2": {"definition": "precround((r1)/resource2x,2)", "templateType": "anything", "group": "Ungrouped variables", "name": "scalingfactor2", "description": ""}, "resource1y": {"definition": "//How much of resource 1 Y uses per unit\nrandom(50..70)", "templateType": "anything", "group": "Ungrouped variables", "name": "resource1y", "description": ""}, "resource1x": {"definition": "//How much of resource 1 X uses per unit\nrandom(20..40)", "templateType": "anything", "group": "Ungrouped variables", "name": "resource1x", "description": ""}, "xconstraint": {"definition": "//least allocation of X - forced\nrandom(4..10)", "templateType": "anything", "group": "Ungrouped variables", "name": "xconstraint", "description": ""}, "constraint2xvalue": {"definition": "round(scalingfactor2*resource2y+xconstraint)", "templateType": "anything", "group": "Ungrouped variables", "name": "constraint2xvalue", "description": ""}, "resource2x": {"definition": "////How much of resource 2 X uses per unit\nrandom(250..450#10)", "templateType": "anything", "group": "Ungrouped variables", "name": "resource2x", "description": ""}, "resource2y": {"definition": "//How much of resource 2 Y uses per unit\nrandom(1500..3000#100)", "templateType": "anything", "group": "Ungrouped variables", "name": "resource2y", "description": ""}, "profity": {"definition": "//the coeff of y in the objective function\nceil(profitx*(resource1y/resource1x)*random(1.5..3))", "templateType": "anything", "group": "Ungrouped variables", "name": "profity", "description": ""}, "profitx": {"definition": "//the coeff of x in the objective function\nrandom(2..4)", "templateType": "anything", "group": "Ungrouped variables", "name": "profitx", "description": ""}, "r2": {"definition": "//the first constraint line cuts the xconstraint line at this value \n//greater than where the second constraint cuts.\nrandom(5..15)", "templateType": "anything", "group": "Ungrouped variables", "name": "r2", "description": ""}, "constraint1yvalue": {"definition": "//Where line given by resource 1 constraint cuts the x=xconstraint line. \n//It is always greater than the point at which the second resource line cuts.\nr2+constraint2yvalue", "templateType": "anything", "group": "Ungrouped variables", "name": "constraint1yvalue", "description": ""}, "totalresource1": {"definition": "siground(scalingfactor1*resource1x*resource1y+resource1y*yconstraint+resource1x*xconstraint,3)", "templateType": "anything", "group": "Ungrouped variables", "name": "totalresource1", "description": ""}, "totalresource2": {"definition": "siground(scalingfactor2*resource2x*resource2y+resource2y*yconstraint+resource2x*xconstraint,3)", "templateType": "anything", "group": "Ungrouped variables", "name": "totalresource2", "description": ""}}, "metadata": {"notes": "

The following variables can be changed by the author to fit their own examples:

\n

xconstraint, yconstraint, resource1x, resource1y,resource2x,resource2y, profitx,profity,r1,r2. All other variables are calculated from these.

\n

See individual variables in the variables list for an explanation of these.

\n

You can also change the names; X, Y, Resource 1, Resource 2, profit......

", "description": "

Template type question.

\n

Authors can change values of some of the variables (see Author's Notes). Also change names to suit the example.

\n

", "licence": "None specified"}, "type": "question", "showQuestionGroupNames": false, "question_groups": [{"name": "", "pickingStrategy": "all-ordered", "pickQuestions": 0, "questions": []}]}, {"name": "Stephanie's copy of Linear Programming 4", "extensions": ["jsxgraph"], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "contributors": [{"name": "Stephanie Greaves", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/340/"}], "functions": {"diagram": {"definition": "var xconstraint=Xforecast-Xstock;\nvar yconstraint=Yforecast-Ystock;\nvar xboundA=(Atime*60-YtimeA*(yconstraint))/XtimeA+5;\nvar xboundB=(Btime*60-YtimeB*(yconstraint))/XtimeB+5;\nvar te=(xboundA >=xboundB);\nvar xbound=Math.max(xboundA,xboundB);\nvar yboundA=(Atime*60-XtimeA*(xconstraint))/YtimeA+5;\nvar yboundB=(Btime*60-XtimeB*(xconstraint))/YtimeB+5;\nvar te1=(yboundA >=yboundB);\nvar ybound=xbound;\nvar solpt;\nvar solx;\nvar soly;\nvar stockleft=-xconstraint-yconstraint;\nvar Afunction=function(x){return (Atime*60-XtimeA*x)/YtimeA;};\nvar Bfunction=function(x){return (Btime*60-XtimeB*x)/YtimeB;};\nvar SLfunction=function(x,y){return x+y+stockleft;};\nvar pt;\nvar div = Numbas.extensions.jsxgraph.makeBoard('400px','400px',\n{boundingBox:[-1,ybound,xbound,-10],\n axis:true,\n showNavigation:false,\n grid:true});\nvar brd=div.board;\n//Create lines using homogeneous coordinates - beware,ax+by+c=0\n//is entered as [c,a,b]\nvar Bline=brd.create('line',[-60*Btime,XtimeB,YtimeB],{name:'Machine B',withLabel:true,fixed:true});\nvar Aline=brd.create('line',[-60*Atime,XtimeA,YtimeA],{name:'Machine A',withLabel:true,fixed:true});\nvar ep=brd.create('intersection',[Aline,Bline],{name:'T',withLabel:true,face:'x',fixed:true});\n\nvar xconst=brd.create('segment',[[xconstraint,0],[xconstraint,ybound]],{strokeColor:'red',fixed:true});\nvar yconst=brd.create('segment',[[0,yconstraint],[xbound,yconstraint]],{strokeColor:'red',fixed:true});\n\nvar al=brd.create('point',[xconstraint,yconstraint],{name:'P',face:'x',fixed:true});\nvar be;\nvar ga;\nvar machine;\nif(te)\n {be=brd.create('point',[xboundA-5,yconstraint],{name:'Q',face:'x',fixed:true});}\nelse \n {be=brd.create('point',[xboundB-5,yconstraint],{name:'Q',face:'x',fixed:true});}\nif(te1)\n{ga=brd.create('point',[xconstraint,Afunction(xconstraint)],{name:'R',face:'x',fixed:true});}\nelse\n {ga=brd.create('point',[xconstraint,Bfunction(xconstraint)],{name:'R',face:'x',fixed:true});}\n//var del=brd.create('point',[xconstraint,Bfunction(xconstraint)],{name:'S',face:'x',fixed:true});\nif(!te&& te1){\n brd.create('polygon',[al,be,ep,ga],{name:\"Feasible Region\",withLabel:false});}\n \n else{\n brd.create('polygon',[al,be,ga],{name:\"Feasible Region\",withLabel:false});\n }\nif(SLfunction(be.X(),be.Y())>SLfunction(ga.X(),ga.Y()))\n {solx=be.X();soly=be.Y();pt='Q';if(te){machine='A';} else {machine='B';}}\nelse \n{solx=ga.X();soly=ga.Y();pt='R';if(te1){machine='A';} else {machine='B';}}\n \n\nsolx=Numbas.math.precround(Numbas.math.niceNumber(solx),1);\nsoly=Numbas.math.precround(Numbas.math.niceNumber(soly),1);\nvar s=brd.create('slider',[[5, 5], [15,5], [0, solx+soly-(xconstraint+yconstraint), 100]],{name:'Stock left'});\nvar st=brd.create('line',[function(){return (-xconstraint-yconstraint)-s.Value();},1,1],{strokeColor:'green',dash:1,name:'Stock left',withLabel:true});\nvar t1 = brd.create('text',[0,-7,\"solutions:x= \"+solx+\",y= \"+soly]);\n$('#xsol').text(solx);\n$('#ysol').text(soly);\nstockleft=Numbas.math.precround(Numbas.math.niceNumber(solx+soly-(xconstraint+yconstraint)),1);\n$('#stckleft').text(stockleft);\n$('#ptname').text(pt);\n$('#machine').text(machine);\nreturn div;\n", "type": "html", "language": "javascript", "parameters": [["XtimeA", "number"], ["YtimeA", "number"], ["XtimeB", "number"], ["YtimeB", "number"], ["Xstock", "number"], ["Ystock", "number"], ["Atime", "number"], ["Btime", "number"], ["Xforecast", "number"], ["Yforecast", "number"]]}, "userinput": {"definition": "\nvar xconstraint=Xforecast-Xstock;\nvar yconstraint=Yforecast-Ystock;\nvar xboundA=(Atime*60-YtimeA*(yconstraint))/XtimeA+5;\nvar xboundB=(Btime*60-YtimeB*(yconstraint))/XtimeB+5;var yboundA=(Atime*60-XtimeA*(xconstraint))/YtimeA+5;\nvar yboundB=(Btime*60-XtimeB*(xconstraint))/YtimeB+5;\nvar xbound=Math.max(xboundA,xboundB,yboundA,yboundB);\nvar ybound=xbound;\nvar div = Numbas.extensions.jsxgraph.makeBoard('400px','400px',{\n boundingBox:[-1,ybound,xbound,-5],\n axis:true,\n showNavigation:false,\n grid:true\n});\nvar board=div.board;\nvar s=board.create('slider',[[5, 5], [15,5], [0, 0, 50]],{name:'Stock left'});\nvar stockleft=-xconstraint-yconstraint;\nvar st=board.create('segment',[[function(){return -stockleft+s.Value();},0],[0,function(){return -stockleft+s.Value();}]],{strokeColor:'green',dash:1,name:'Stock left',withLabel:true});\nquestion.signals.on('HTMLAttached',function(e) {\n \n //set up KO observables to compute the coordinates from the student's input\n var xcon = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[0].display.studentAnswer());\n });\n var ycon = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[1].display.studentAnswer());\n });\n var aa = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[2].display.studentAnswer());\n });\n var ba = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[3].display.studentAnswer());\n });\n var ca = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[4].display.studentAnswer());\n });\n var ta_coordinates = ko.computed(function() {\nif(isNaN(aa()) || isNaN(ba()) || isNaN(ca())) {\n // return [0,0,1];\n}\nreturn [-ca(),aa(),ba()];\n });\n \n // create the lines\n var x_constraint_line = board.create('line',[[xcon,0],[xcon,1]],{strokeColor:'red',fixed:true, straightFirst: false});\n var y_constraint_line = board.create('line',[[0,ycon],[1,ycon]],{strokeColor:'red',fixed:true, straightFirst: false});;\n var inequality_linea = board.create('line',[ta_coordinates]);\n var ab = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[5].display.studentAnswer());\n });\n var bb = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[6].display.studentAnswer());\n });\n var cb = ko.computed(function() {\nreturn parseFloat(question.parts[0].gaps[7].display.studentAnswer());\n });\n var tb_coordinates = ko.computed(function() {\nif(isNaN(ab()) || isNaN(bb()) || isNaN(cb())) {\n // return [0,0,1];\n}\nreturn [-cb(),ab(),bb()];\n });\n \n var inequality_lineb = board.create('line',[tb_coordinates]);\n var ep=board.create('intersection',[inequality_linea,inequality_lineb],{name:'T',face:'x',visible:false});\n var al=board.create('point',[xcon,ycon],{name:'P',face:'x',fixed:true});\n var be1=board.create('intersection',[inequality_linea,y_constraint_line],{name:'Q',face:'x',fixed:true,visible:false});\n var be2=board.create('intersection',[inequality_lineb,y_constraint_line],{name:'Q',face:'x',fixed:true,visible:false});\n var ga=board.create('intersection',[x_constraint_line,inequality_linea],{name:'R',face:'x',fixed:true,visible:false});\n var del=board.create('intersection',[x_constraint_line,inequality_lineb],{name:'R',face:'x',fixed:true,visible:false});\n var fr1=board.create('polygon',[al,be2,ep,ga],{name:\"Feasible Region\",visible:false}); \n var fr2=board.create('polygon',[al,be1,ga],{name:\"Feasible Region\",visible:false}); \n var fr3=board.create('polygon',[al,be2,del],{name:\"Feasible Region\",visible:false}); \n ko.computed(function(){ \n// look at the observables, so this function gets called whenever they change\nxcon(),ycon(),ta_coordinates(),tb_coordinates();\n\nvar lineAOK=!(isNaN(aa()) || isNaN(ba()) || isNaN(ca()));\nvar lineBOK=!(isNaN(ab()) || isNaN(bb()) || isNaN(cb()));\nvar consxOK= !isNaN(xcon());var consyOK= !isNaN(ycon());\n// show/hide the lines based on whether the student input is valid\nvar te=(be1.X()> be2.X());\nvar te1=(ga.Y()> del.Y());\nx_constraint_line.setAttribute({'visible':consxOK});\ny_constraint_line.setAttribute({'visible': consyOK}); \ninequality_linea.setAttribute({'visible': lineAOK});\ninequality_lineb.setAttribute({'visible': lineBOK});\nal.setAttribute({'visible':consxOK&&consyOK});\nep.setAttribute({'visible':((lineAOK&&lineBOK))&&((!te)&&te1)});\nbe1.setAttribute({'visible':lineAOK&&te});\nbe2.setAttribute({'visible':lineBOK&&(!te)});\nga.setAttribute({'visible':(lineAOK&&consxOK)&&te1});\ndel.setAttribute({'visible':(lineBOK&&consxOK)&&(!te1)}); \nvar fr1_visible = ((consxOK&&consyOK)&&(lineAOK&&lineBOK))&&((!te)&&te1);\nvar fr2_visible = consxOK&&consyOK&&lineAOK&&lineBOK&&te&&te1;\nvar fr3_visible = consxOK&&consyOK&&lineAOK&&lineBOK&&(!te)&&(!te1);\nfr1.setAttribute({'visible':fr1_visible, 'fillOpacity': fr1_visible ? 0.3 : 0});\nfr2.setAttribute({'visible':fr2_visible, 'fillOpacity': fr2_visible ? 0.3 : 0}); \nfr3.setAttribute({'visible':fr3_visible, 'fillOpacity': fr3_visible ? 0.3 : 0}); \n// prompt JSXGraph to reevaluate the coordinate functions\nboard.update(); \n }); \n});\n\nreturn div;\n", "type": "html", "language": "javascript", "parameters": [["XtimeA", "number"], ["YtimeA", "number"], ["XtimeB", "number"], ["YtimeB", "number"], ["Xstock", "number"], ["Ystock", "number"], ["Atime", "number"], ["Btime", "number"], ["Xforecast", "number"], ["Yforecast", "number"]]}}, "ungrouped_variables": ["yconstraint", "xstock", "xforecast", "xtimea", "atime", "xtimeb", "xconstraint", "btime", "timeforb", "r1", "timefora", "r2", "ytimeb", "ystock", "ytimea", "yforecast"], "tags": ["Feasible region", "Jsxgraph", "constraints", "graphical method", "jsxgraph", "linear programming", "maximise", "objective function"], "preamble": {"css": "", "js": ""}, "advice": "

{diagram(xtimea,ytimea,xtimeb,ytimeb,xstock,ystock,atime,btime,xforecast,yforecast)}

\n

The constraints are:

\n

$\\var{xtimea}x + \\var{ytimea}y \\leq \\var{atime}\\times 60 =\\var{atime*60}$ machine A time.

\n

$\\var{xtimeb}x + \\var{ytimeb}y \\leq \\var{btime}\\times 60 =\\var{btime*60}$ machine B time.

\n

$x \\geq \\var{xforecast} -\\var{xstock}=\\var{xforecast-Xstock}$

\n

This ensures that production of bicycles $\\geq$ demand ($\\var{xforecast}$) - initial stock ($\\var{xstock}$)  and so meets demand.

\n

$y \\geq \\var{yforecast} -\\var{ystock}=\\var{yforecast-ystock}$.

\n

This ensures that production of scooters $\\geq$ demand ($\\var{yforecast}$) - initial stock ($\\var{ystock}$)  and so meets demand.

\n

The objective is: maximise $(x+\\var{xstock}-\\var{xforecast}) + (y+\\var{ystock}-\\var{yforecast}) = \\simplify{x+y+{xstock+ystock-xforecast-yforecast}}$
i.e. to maximise the number of units left in stock at the end of the week

\n

The Feasible region is the green area and we have moved the Stock left objective function line to the position where it intersects the Feasible region and maximises Stock left.

\n

We find using the graphical method that using Machine : $x=\\;$,    $y=\\;$,     Stock left =

\n

This occurs at the point in the above diagram.

\n

Your graphical solution may differ slightly from these as it is not always possible to get the objective line accurately through the desired point. Also, if these numbers are not whole numbers then you can easily find a whole number solution near these and any such reasonable solution near the above solutions is fine as long as it lies in the Feasible region.

", "rulesets": {}, "parts": [{"prompt": "

Let $x,\\;y$ be the number of bicycles and scooters produced respectively.

\n

{userinput(xtimea,ytimea,xtimeb,ytimeb,xstock,ystock,atime,btime,xforecast,yforecast)}

\n

What are the constraints on production given the forecasts for bicycles and scooters and the stock levels?

\n

$x \\ge\\;$[[0]]      $y \\ge\\;$[[1]]

\n

Time inequality for Machine A: [[2]]$x\\;+\\;$[[3]]$y\\;\\le\\;$[[4]]   (in minutes)

\n

Time inequality for Machine B: [[5]]$x\\;+\\;$[[6]]$y\\;\\le\\;$[[7]]   (in minutes)

\n

Input the objective function which maximises Stock left.

\n

Objective function: [[8]]

\n

Note that the objective function Stock left is displayed above for the values of $x$ and $y$ which just clear demand i.e. Stock left=0. Once you have input all of the constraints you can use the slider to move the objective function to the value of $x$ and $y$ in the Feasible region to maximise Stock left.

\n

Using this diagram find values of the production of $x$ and $y$ which satisfy the constraints and maximise the amount of stock $x+y$ left at the end of the week.

\n

", "marks": 0, "gaps": [{"allowFractions": false, "marks": 1, "maxValue": "xconstraint", "minValue": "xconstraint", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "yconstraint", "minValue": "yconstraint", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "xtimea", "minValue": "xtimea", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "ytimea", "minValue": "ytimea", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "atime*60", "minValue": "atime*60", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "xtimeb", "minValue": "xtimeb", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "ytimeb", "minValue": "ytimeb", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"allowFractions": false, "marks": 1, "maxValue": "btime*60", "minValue": "btime*60", "correctAnswerFraction": false, "showCorrectAnswer": true, "scripts": {}, "type": "numberentry", "showPrecisionHint": false}, {"vsetrangepoints": 5, "expectedvariablenames": [], "checkingaccuracy": 0.001, "vsetrange": [0, 1], "showpreview": true, "marks": 1, "showCorrectAnswer": true, "answersimplification": "all", "scripts": {}, "answer": "x+y-{xconstraint+yconstraint}", "checkingtype": "absdiff", "checkvariablenames": false, "type": "jme"}], "showCorrectAnswer": true, "scripts": {}, "type": "gapfill"}], "statement": "

A company makes two products (bicycles and scooters) using two machines (A and B).

\n

Each bicycle that is produced requires $\\var{XtimeA}$ minutes processing time on machine A and $\\var{XtimeB}$ minutes processing time on machine B.

\n

Each scooter that is produced requires $\\var{YtimeA}$ minutes processing time on machine A and $\\var{YtimeB}$ minutes processing time on machine B.

\n

Either Machine A or Machine B will be used given there is only one available operator.

\n

At the start of the current week there are $\\var{Xstock}$ bicycles and $\\var{Ystock}$ scooters in stock.

\n

Available processing time on machine A is forecast to be $\\var{Atime}$ hours and on machine B is forecast to be $\\var{Btime}$ hours.

\n

The demand for bicycles in the current week is forecast to be $\\var{Xforecast}$ units and for scooters is forecast to be $\\var{Yforecast}$ units.

\n

Company policy is to maximise the combined sum of the units of bicycles and the units of scooters in stock at the end of the week.

\n\n

\n

(Author of original problem: J E Beasley: http://people.brunel.ac.uk/~mastjjb/jeb/or/rights.html)

", "variable_groups": [], "variablesTest": {"maxRuns": 100, "condition": ""}, "variables": {"yconstraint": {"definition": "\n//Difference between forecast demand and stock, \n//so more than this have to be created to meet demand .\nrandom(6..15)\n", "templateType": "anything", "group": "Ungrouped variables", "name": "yconstraint", "description": ""}, "xstock": {"definition": "\n//Amount in stock for X at beginning of week\nrandom(10..40)\n", "templateType": "anything", "group": "Ungrouped variables", "name": "xstock", "description": ""}, "xforecast": {"definition": "xconstraint+xstock", "templateType": "anything", "group": "Ungrouped variables", "name": "xforecast", "description": ""}, "xtimea": {"definition": "random(50..100)", "templateType": "anything", "group": "Ungrouped variables", "name": "xtimea", "description": ""}, "yforecast": {"definition": "yconstraint+ystock", "templateType": "anything", "group": "Ungrouped variables", "name": "yforecast", "description": ""}, "ystock": {"definition": "\n//Amount in stock for Y at beginning of week\nrandom(70..100)\n", "templateType": "anything", "group": "Ungrouped variables", "name": "ystock", "description": ""}, "xconstraint": {"definition": "\n//Difference between forecast demand and stock, \n//so more than this have to be created to meet demand .\nrandom(30..60)\n", "templateType": "anything", "group": "Ungrouped variables", "name": "xconstraint", "description": ""}, "btime": {"definition": "\n//time buffer for Machine B (in hours).\n//if you add on a small number of hours on timeforb then you \n//will restrict the feasible area.\nround((timeforb+random(500..1000))/60)\n", "templateType": "anything", "group": "Ungrouped variables", "name": "btime", "description": ""}, "timeforb": {"definition": "\n//least amount of time that Machine B has to work.\nxconstraint*xtimeb+yconstraint*ytimeb\n", "templateType": "anything", "group": "Ungrouped variables", "name": "timeforb", "description": ""}, "r1": {"definition": "\n//slope of line for Machine A\nrandom(2.0..3.0#0.05)\n", "templateType": "anything", "group": "Ungrouped variables", "name": "r1", "description": ""}, "timefora": {"definition": "\n//least amount of time that Machine A has to work.\nxconstraint*xtimea+yconstraint*ytimea\n", "templateType": "anything", "group": "Ungrouped variables", "name": "timefora", "description": ""}, "r2": {"definition": "\n//slope of line for Machine B, less than that for Machine A\nrandom(0.3..1.5#0.05 except 1.0)\n", "templateType": "anything", "group": "Ungrouped variables", "name": "r2", "description": ""}, "ytimeb": {"definition": "round(xtimeb/r2)", "templateType": "anything", "group": "Ungrouped variables", "name": "ytimeb", "description": ""}, "atime": {"definition": "\n//time buffer for Machine A (in hours).\n//if you add on a small number of hours to timefora then you \n//will restrict the feasible area.\nround((timefora+random(500..1000))/60)\n", "templateType": "anything", "group": "Ungrouped variables", "name": "atime", "description": ""}, "ytimea": {"definition": "\n//ensures slope is approx r1\nround(xtimea/r1)\n", "templateType": "anything", "group": "Ungrouped variables", "name": "ytimea", "description": ""}, "xtimeb": {"definition": "random(25..50)", "templateType": "anything", "group": "Ungrouped variables", "name": "xtimeb", "description": ""}}, "metadata": {"notes": "

05/01/2014:

\n

First version finished with functions supplied by CP.

\n

Display needs improving.

", "description": "

Graphical linear program example. Two machines both producing the same 2 products with varying times of production for each product and time constraints on machine use in a week. Given stock at the beginning of the week together with a forecast demand to be met, find production which maximises stock at the end of the week.

\n

(Author of original problem: J E Beasley: http://people.brunel.ac.uk/~mastjjb/jeb/or/rights.html)

", "licence": "None specified"}, "type": "question", "showQuestionGroupNames": false, "question_groups": [{"name": "", "pickingStrategy": "all-ordered", "pickQuestions": 0, "questions": []}]}], "pickQuestions": 0}], "navigation": {"onleave": {"action": "none", "message": ""}, "reverse": true, "allowregen": true, "preventleave": true, "browse": true, "showfrontpage": true, "showresultspage": "never"}, "duration": 0, "metadata": {"notes": "", "description": "

Questions on linear programming techniques, with interactive graphics.

", "licence": "Creative Commons Attribution 4.0 International"}, "allQuestions": true, "shuffleQuestions": false, "questions": [], "percentPass": 0, "timing": {"allowPause": true, "timeout": {"action": "none", "message": ""}, "timedwarning": {"action": "none", "message": ""}}, "pickQuestions": 0, "type": "exam", "showQuestionGroupNames": false, "feedback": {"showtotalmark": true, "advicethreshold": 0, "showanswerstate": true, "showactualmark": true, "allowrevealanswer": true}, "contributors": [{"name": "Denis Flynn", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/1216/"}], "extensions": ["jsxgraph", "stats"], "custom_part_types": [], "resources": []}