Discount calculator - calculator
Good day, I am new to programming and im trying my hand at a discount calculator that is written in pascal. Sadly i am having some issues. I am posting my code and i am hoping you all could point out where i went wrong.
program Discount_Calulator;
{Name: Yohan Henry}
{Date: 28.02.2014}
{Purpose:To accept the customer name and total payment then calculate the discount given to the customer then finally print the customer's name, customer's total payment, customer's discount, customer's after discount price and total discount}
Var
Total_discount: real;
[Y]: integer; {Here I listed all my variables I needed to make the program}
After_discount Array [1.20]: real;
Establishment Array [1.20]: real;
Total_payment Array [1.20]: real;
Discount Array [1.20]: real;
Begin
start
clscr;
Total Discount := 0;
FOR Y := 1 to 20 DO
After_discount [Y] := 0; {Here Initialized my variables to make it easier to run}
Total_payment [Y] := 0;
Discount [y] ;= 0;
END FOR
FOR [Y] := 1 to 20 DO
writeln 'Enter Customer Name';
readln 'Establishment [Y]';
writeln 'Enter the Customer's Total Payment';
reanln 'Total_payment [Y]';
END FOR
FOR [Y] := 1 to 20 DO
IF Total_payment [Y] >= 15000 THEN
Discount [Y] := Total_payment [Y] * 0.10;
END IF
IF Total_payment [Y] >= 12500 AND
Total_payment [Y] < 15000 THEN
Discount [Y] := Total_payment [Y] * 0.05
END IF
IF Total_payment [Y] > 10500 AND
Total_payment [Y] < 12500 THEN
Discount [Y] := Total_payment [Y] * 0.02
END IF
After_discount [Y] := Total_payment [Y] - Discount [Y]
Total_discount [Y] := Total_discount [Y] + Discount [Y]
END FOR [Y] := 1;
WHILE [Y] <= 20 DO
WHILE LOOP TO PRINT
writeln 'The Customer Name is Establishment [Y]'
writeln 'The Total_payment of the Customer is $x', Total_payment [Y]'
writeln 'The Customer Discount is $x', Discount [Y]'
writeln 'The Customer Price after Discount is $x', After_discount [Y]'
Y := Y + 1
writeln 'The Total Overall Discount is $x', Total_discount [Y]
END.
I spotted one: Around where you say "{Here Initialized my variables to make it easier to run}", Discount [y] ;= 0; must be Discount [y] := 0;. I can imagine that the error message is not clear on that kind of syntax error.
And then I spotted a "reanln" ("readln"?). If this is the original code you tried to translate the compiler probably complained.
Related
Maple error - "illegal use of a formal parameter"
I'M TRYIN TO CREATE A PROGRAM USING MAPLE FOR GAUSSING ELIMINATION BUT I KEEP GETTING THIS ERROR Gauss := proc (n::posint, A::matrix, c::Vector) local a, i, k, j, p; with(MTM): n := linalg[rowdim](A); if det(A) = 0 then print('matrice*doit*etre*caree') else if det(A) <> 0 then a := `<|>`(A, c); for k to n-1 do for i from k+1 to n do if a[i, i] = 0 then swaprow(a, k, i) else p = a[i, k]/a[k, k]; for j from k+1 to n+1 do a[i, j] = a[i, j]-p*a[k, j] end do; end if; end do; end do; else print('rien') end if; end if; end proc; Error, (in Gauss) illegal use of a formal parameter
restart; Gauss := proc(A::Matrix, c::Vector) local a, i, k, j, m, n, p; n := linalg[rowdim](A); m := linalg[coldim](A); if m <> n then print("matrice doit etre caree"); else a := `<|>`(A, c); for k to n-1 do for i from k+1 to n do if a[i, i] = 0 then a := linalg[swaprow](a, k, i); else p := a[i, k]/a[k, k]; for j from k to n+1 do a[i, j] := a[i, j]-p*a[k, j]; end do; end if; end do; end do; end if; return a; end proc: c := Vector([2, 3, 4]); A := Matrix(3, 3, [4, 1, 2, 3, 6, 5, 2, 1, 9]); Gauss(A, c); LinearAlgebra:-LUDecomposition(<A|c>, output=U); There were quite a few mistakes, so let's hope I get most of them. I didn't bother doing 7. You should do it. You cannot use with inside a procedure. Your code uses commands from thelinalg package, not the MTM package. Ideally you'd use Matrix&Vector&LinearAlgebra (instead of your mix of matrix&Vector&linalg(. Your procedure has n as one of its parameters, but inside it you also try to assign a value to n, the argument for which you passed in as the number 3. That's where your error message is coming from. You can't do that. Several of you lines have just = instead of := for assignments. The = does nothing. The test against det(A)=0 is wrong is wrong in several ways. I'll just say that it doesn't actually test whether the A is square. Compare the row & column dimensions if you want to test that A is square. You should be using LinearAlgebra equivalents instead of the linalg commands commands swaprow, coldim. You forgot to have your procedure actually return the Matrix a. When your code calls swaprow is was not actually updating a. It was just throwing way the result. It's a sin to not indent your code. It will lead you to overlook mistakes.
figure out math formula for spaces in pascal diamond project
How is it going guys ? I've written a program that "draws" diamond in the command line (it's a part of my homework). For spaces inside the diamond I was given a formula "1 + 2(k-2) or 2k -3 , where k is line number", but I don't understand how this formula was created. Could anyone explain it ? program diamond; var n, k, h, i: integer; begin repeat write('Enter the diamond''s height (positive odd): '); readln(h); until (h > 0) and (h mod 2 = 1); n := h div 2; for k := 1 to n + 1 do begin for i := 1 to n + 1 - k do write(' '); write('*'); if k > 1 then begin for i := 1 to 2*k - 3 do write(' '); write('*') end; writeln end; for k := n downto 1 do begin for i := 1 to n + 1 - k do write(' '); write('*'); if k > 1 then begin for i := 1 to 2*k - 3 do write(' '); write('*') end; writeln end end.
I've already figured it out. It's a simple, but modified arithmetic progression An=A1-d(n-2). Usually we would use (n-1), but because we need to substract 2 stars from each line (starting from the second one, as this formula works for k>1), we use (n-2)
Minizinc Objective Function For Gaps in Schedule
I have a working Miniznic model to schedule individual lessons of 1 professor having n students (Optimization Problem of a Single Lessons Scheduling Model). The model considers availability (hard constraint) and the time preferences (objective function) of the professor as well as of the students. Now, I want to extend the model and optimize the schedule such that gaps between lessons are minimized. Example: Schedule : p L p p L L . . p p L L p L L p L p p . L p L L . L p L Real Gaps : . L p p L L . . . . L L p L L p L . . . L p L L . L p L where `p` = 0 == Teacher available, but no Lesson `L` = 1 == Teacher gives lesson (to student) `.` = -1 == Teacher not available Obviously, the p in slot 1 must not be counted as a gap. Similarly, slots 9 and 10 are no gaps, neither. Eliminating all false gaps, the Schedule should finally look like the Real Gaps array (Note: false gaps are marked with .; the same as not available). The result would be a gap array [2, 1, 1, 1, 1] (for each gap showing the number of slots it lasts). Based on such an array one could then e.g. formulate an objective to minimize the overall gap slots. In ruby I was able to formulate an algorithm that does what I want: def gap_array(schedule_arr) # initialize variables start_search = false # flag for break start break_slots = 0 # counter of break slots res_arr = [] # resulting array schedule_arr.each do |slot| if slot == 1 # start watching for break start_search = true end # if start_search if slot == 0 # == break break_slots += 1 elsif slot == 1 # == consecutive lesson slot if break_slots > 0 # number of break_slots > 0 res_arr.append(break_slots) break_slots = 0 end else # == not available break_slots = 0 # any break so far is discarded start_search = false end end end return res_arr end How can I formulate such an algorithm in Minizinc? Thanks!
One way to this in MiniZinc would be to extend the model at Optimization Problem of a Single Lessons Scheduling Model in the following way: Initially calculate teacher_free as the slots where the teacher is not available combined with adjacent slots where no lesson takes place (this is done in two steps, going from the left teacher_free_left and the right teacher_free_right, respectively, and then combining the results to form teacher_free). In the next step the real_gap is calculated as slots where the teacher is not free and no lesson takes place. In the objective a penalty term for real_gap is then introduced like (k2 being the gap penalty weight): int: k2 = 1; var int: obj = sum(s in STUDENT, t in TIME) (active[s,t] * (prio_time[s,t] + k*prioTeacher_time[t])) - k2*sum(real_gap); Here all the other extensions to the model (with some further comments): array[DAY,SLOT] of var 0..1: lesson = array2d(DAY, SLOT, [sum(s in STUDENT)(active[s,time(d,z)]) | d in DAY, z in SLOT]); array[DAY,SLOT] of var 0..1: teacher_free_left; array[DAY,SLOT] of var 0..1: teacher_free_right; array[DAY,SLOT] of var 0..1: teacher_free; array[DAY,SLOT] of var 0..1: real_gap; predicate equals_and(var 0..1: z, var 0..1: x, var 0..1: y) = (z <= x /\ z <= y /\ z >= x + y - 1); predicate equals_or(var 0..1: z, var 0..1: x, var 0..1: y) = (z >= x /\ z >= y /\ z <= x + y); % calculate teacher free left % first slot -> teacher free = no lesson in the slot % other slots -> teacher free = teacher out or (left slot teacher free and no lesson in slot) array[DAY,SLOT] of var 0..1: teacher_free_left_temp; constraint forall(d in DAY) (teacher_free_left_temp[d,1]=1-lesson[d,1]); constraint forall(d in DAY, z in 2..maxSlots) (equals_and(teacher_free_left_temp[d,z], teacher_free_left[d,z-1], 1-lesson[d,z])); constraint forall(d in DAY, z in SLOT) (equals_or(teacher_free_left[d,z], 1 - bool2int(z in teacher[d]), teacher_free_left_temp[d,z])); % calculate teacher free right % last slot -> teacher free = no lesson in the slot % other slots -> teacher free = teacher out or (right slot teacher free and no lesson in slot) array[DAY,SLOT] of var 0..1: teacher_free_right_temp; constraint forall(d in DAY) (teacher_free_right_temp[d,maxSlots]=1-lesson[d,maxSlots]); constraint forall(d in DAY, z in 1..maxSlots-1) (equals_and(teacher_free_right_temp[d,z], teacher_free_right[d,z+1], 1-lesson[d,z])); constraint forall(d in DAY, z in SLOT) (equals_or(teacher_free_right[d,z], 1 - bool2int(z in teacher[d]), teacher_free_right_temp[d,z])); % teacher free when teacher free left or teacher free right constraint forall(d in DAY, z in SLOT) (equals_or(teacher_free[d,z], teacher_free_left[d,z], teacher_free_right[d,z])); % real gap when teacher not free and no lesson constraint forall(d in DAY, z in SLOT) (equals_and(real_gap[d,z], 1-teacher_free[d,z], 1-lesson[d,z]));
Optimization Problem of a Single Lessons Scheduling Model
I've written a Minizinc-Model that allows a teacher to schedule single lessons of his students. Teacher and students can prioritize their available time slots (prioTeacher, respectively prio). The model works fine for simple and small input sets, but with a realistic set of input data, i.e. 3 days, each having 44 time slots (== 15 minutes) and 11 students, didn't find the optimal solution after more than 24 hours. Model (stupla-prio.mzn) % enum of presence days enum DAY; int: num_days = card(DAY); % maximal duration of a lessons int: maxDur; % maximal numbers of slots per Day; int: maxSlots; set of int: SLOT = 1..maxSlots; set of int: SLOTx = 0..maxSlots; % number of students int: n; set of int: STUDENT = 1..n; % array[DAY] of set of SLOT: teacher; array[STUDENT,DAY] of set of SLOT: feasible; array[STUDENT] of 1..maxDur: lessonDuration; array[STUDENT,DAY,SLOT] of 0..3: prio; array[DAY,SLOT] of 0..3: prioTeacher; % Factor for weighting: obj = obj_stud + k * obj_teacher int: k; % % decision VARIABLES % array[STUDENT,DAY] of var 0..maxSlots: start_slot; array[STUDENT,DAY] of var SLOTx: start_slot; array[STUDENT,DAY] of var SLOTx: end_slot; % 2d-array that stores for each d (in DAYS) and each SLOT % the STUDENT or % 0 if it is not allocated or % -1 the teacher is available neither array[SLOT,DAY] of var -1..n: schedule; % ----------------------------------------------------------- % CONSTRAINTS % 1. For each student 'start_slot' must be in 'feasible' constraint forall(s in STUDENT, d in DAY where start_slot[s,d] > 0)( start_slot[s,d] in feasible[s,d] ); % 2. For each student 'end_slot' = 'start_slot' + lessonDuration - 1 constraint forall(s in STUDENT, d in DAY)( if start_slot[s,d] > 0 then end_slot[s,d] = start_slot[s,d] + lessonDuration[s] - 1 else end_slot[s,d] = 0 endif); % 3. All slot between 'start_slot' and 'end_slot' must be in 'feasible' constraint forall(s in STUDENT, d in DAY where start_slot[s,d] > 0)( forall(j in 1..lessonDuration[s]-1) ( start_slot[s,d] + j in feasible[s,d] ) ); % 4. make sure each student has exactly 1 lesson constraint forall(s in STUDENT)( sum([start_slot[s,d] > 0| d in DAY]) = 1); % 5. link 'schedule' to 'start_slot' and 'end_slot' constraint forall(s in STUDENT, d in DAY, z in SLOT) ( (z in feasible[s,d] /\ z >= start_slot[s,d] /\ z <= end_slot[s,d]) <-> schedule[z,d] = s ); % 6. mark empty slots for teacher constraint forall(d in DAY, z in SLOT)( (z in teacher[d] /\ schedule[z,d] = -1) -> schedule[z,d] = 0 ); % objective function students var int: obj_stud; constraint obj_stud = sum([prio[schedule[z,d],d,z]| d in DAY, z in SLOT where schedule[z,d] > 0]); % objective function teacher var int: obj_teacher; constraint obj_teacher = sum([prioTeacher[d,z]| d in DAY, z in SLOT where schedule[z,d] > 0]); %solve satisfy; solve :: int_search( [start_slot[s,d] |s in STUDENT, d in DAY], first_fail, indomain, complete) maximize (obj_stud + k * obj_teacher); output [ % "start_slot =\n" ++ show2d(start_slot) ++ "\n" ++ % "end_slot = " ++ show2d(end_slot) ++ "\n" ++ % " teacher = " ++ show(teacher) ++ ";\n" ++ % " feasible = " ++ show2d(feasible) ++ "\n" ++ % "schedule = \n" ++ show2d(schedule) ++ ";\n" ++ % " - " " Slot# ||"] ++ [ " \(d) |" | d in DAY ] ++ [ "| obj = " ++ show(obj_stud + k * obj_teacher) ++ " [teacher=\(obj_teacher), " ++ "stud=\(obj_stud), k=\(k)]" ] ++ [ "\n -------++"] ++ [ "-------+" | d in DAY ] ++ ["+\n"] ++ [ if d = 1 then show_int(5,z) ++ " ||" else "" endif ++ show_int(4,schedule[z,d]) ++ " |" ++ if d = num_days then "|\n" else "" endif | z in SLOT, d in DAY ] ++ [ " -------++"] ++ [ "-------+" | d in DAY ] ++ ["+\n"] ; Data example 1 (works fine) DAY = {Mon, Wed}; maxSlots = 14; % == 30 minutes slot duration teacher = [ {1,2,3,4,5,6}, {6,11,12,13,14}]; n = 4; lessonDuration = [2,1,1,3]; maxDur = 3; feasible = array2d(1..n, DAY, [ {1,2,3,4,5,6}, {6}, {1,2,3}, {}, % Stud2: Day1, Day2 {1}, {13,14}, % Stud3: Day1, Day2 {3,4,5}, {11,12,13,14}]); prio = array3d(1..n,DAY,1..maxSlots, [ % Stud1 1,1,1,2,2,2,0,0,0,0,0,0,0,0, 0,0,0,0,0,2,0,0,0,0,0,0,0,0, % Stud2 1,3,3,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0, % Stud3 3,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,2,2, % Stud4 0,0,1,2,2,0,0,0,0,0,0,0,0,0 , 0,0,0,0,0,0,0,0,0,0,3,3,1,1]); % k = 10; prioTeacher = array2d(DAY,1..maxSlots, [ % Example 1: % morning muffel, and break % 1,1,1,2,2,2,3,1,1,3,3,3,3,3, % 1,1,1,2,2,2,3,1,1,3,3,3,3,3,]); % Example 2: % early bird 3,3,3,3,3,3,1,1,1,1,1,1,1,1, 3,3,3,3,3,3,1,1,1,1,1,1,1,1]); Example 2 (takes verrry long...) % Datafile % Available week days DAY = {Mon, Tue, Wed}; % Number of maximal slots per day, == 15 minutes slots maxSlots = 44; % Number of students n = 11; % Weighting factor k = 1; lessonDuration = [3,3,2,3,3,3,3,3,6,4,2]; maxDur = 6; teacher = [ {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44}, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44}, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44}]; % feasible time slots (teacher and students intersected) feasible = array2d(1..n, DAY, [ % IH {1,2,3,4,5,6,7,8}, {}, {1,2,3,4,37,38,39,40,41,42,43}, % MM {11,12,13,14,15,16,28,29,30,31}, {7,8,9,10,11}, {}, % NW {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42}, {}, {1,2,3,4,5,6,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42}, % RD {7,8,9,10,11,12,40,41,42}, {13,14,15,16,17,18,19,20,21,22,23,34,35,36,37,38}, {}, % MS {7,8,9,10,11,12,34,35,36,37,38,39,40,41,42}, {35,36,37,38,39,40}, {}, % SB {}, {1,2,3,4,5,6}, {8,9,10,11,12}, % SO {}, {}, {6,7,8,9,10,11,12,36,37,38,39,40,41,42}, % CT {}, {}, {1,2,3,4,5,6,7,8,9,10,11,12}, % AG {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44}, {9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28}, {}, % SS {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44}, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44}, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44}, % RF {25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42}, {}, {33,34,35,36,37,38,39,40,41,42} ]); % Prioririties of Teacher prioTeacher = array2d(DAY,1..maxSlots, [ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]); % Priorities of Students prio = array3d(1..n,DAY,1..maxSlots, [ % 1. IH 2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,0, % 2. MM 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, % 3. NW 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0, % 4. RD 0,0,0,0,0,0,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, % 5. MS 0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, % 6. SB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, % 7. SO 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,0,0, % 8. CT 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, % 9. AG 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, % 10. SS 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, % 11. RF 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,0]); (You can access the files here: https://gitlab.com/andibachmann/stupla_mzn/tree/master/mzn/t3 ) I did my calculations with mzn-gecode (G12 MiniZinc evaluation driver, version 2.0.2). Any hints and/or directions for further improvements are welcome! Regards Andi
I did the following changes to the model: combined the DAY and SLOT dimensions into a single TIME dimension (parameters are converted accordingly), caution is taken so that lessons don't extend over multiple days. removed the explicit schedule representation of the solution - it is now calculated on-the-fly in the output section. pre-calculated feasible start times for student lessons - thereby only the start times must be constrained in the model. changed to use binary variables start and active that represent if a student lesson starts at a given time and is active at given time, respectively. made all constraints linear in the start and active variables. Using the modified model the OSICBC solver solves the larger instance to optimum within a second. % enum of presence days enum DAY; int: num_days = card(DAY); % maximal duration of a lessons int: maxDur; % maximal numbers of slots per Day; int: maxSlots; set of int: SLOT = 1..maxSlots; set of int: SLOTx = 0..maxSlots; % number of students int: n; set of int: STUDENT = 1..n; % array[DAY] of set of SLOT: teacher; array[STUDENT,DAY] of set of SLOT: feasible; array[STUDENT] of 1..maxDur: lessonDuration; array[STUDENT,DAY,SLOT] of 0..3: prio; array[DAY,SLOT] of 0..3: prioTeacher; % Factor for weighting: obj = obj_stud + k * obj_teacher int: k; % Make the time axis one-dimensional and convert all data accordingly. set of int: TIME = 1..maxSlots*num_days; function int: time(int: d, int: z) = (d-1)*maxSlots + z; set of TIME: teacher_time = {time(d, z) | d in DAY, z in teacher[d]}; array[STUDENT] of set of TIME: feasible_time = [{time(d, z) | d in DAY, z in feasible[s,d]} | s in STUDENT]; array[STUDENT] of set of TIME: feasible_start_time = [{time(d,z) | d in DAY, z in 1..maxSlots-lessonDuration[s]+1 where forall(u in time(d,z)..time(d,z)+lessonDuration[s]-1)(u in feasible_time[s] intersect teacher_time)} | s in STUDENT]; array[STUDENT,TIME] of 0..3: prio_time = array2d(STUDENT, TIME, [prio[s,d,z] | s in STUDENT, d in DAY, z in SLOT]); array[TIME] of 0..3: prioTeacher_time = [prioTeacher[d,z] | d in DAY, z in SLOT]; % % decision VARIABLES array[STUDENT,TIME] of var 0..1: start; array[STUDENT,TIME] of var 0..1: active; % ----------------------------------------------------------- % CONSTRAINTS % 1. a lesson can only start at a feasible time constraint forall(s in STUDENT, t in TIME) (start[s,t] <= bool2int(t in feasible_start_time[s])); % 2. each lesson must have a start time constraint forall(s in STUDENT) (sum(t in TIME)(start[s,t]) = 1); % 3. maximum one lesson active at any time constraint forall(t in TIME) (sum(s in STUDENT)(active[s,t]) <= 1); % 4&5. constraints defining if lesson active constraint forall(s in STUDENT, d in 1..num_days) (active[s,time(d,1)] = start[s,time(d,1)]); constraint forall(s in STUDENT, d in 1..num_days, z in 2..maxSlots) (active[s,time(d,z)] <= active[s,time(d,z-1)] + start[s,time(d,z)]); % 6. ensure duration of lesson is fulfilled constraint forall(s in STUDENT) (sum(t in TIME)(active[s,t]) = lessonDuration[s]); var int: obj = sum(s in STUDENT, t in TIME) (active[s,t] * (prio_time[s,t] + k*prioTeacher_time[t])); solve maximize obj; output [ " Slot# ||"] ++ [ " \(d) |" | d in DAY ] ++ [ "| obj = " ++ show(obj) ++ " [teacher=\(sum(s in STUDENT, t in TIME)(active[s,t] * k*prioTeacher_time[t])), " ++ "stud=\(sum(s in STUDENT, t in TIME)(active[s,t] * prio_time[s,t])), k=\(k)]" ] ++ [ "\n -------++"] ++ [ "-------+" | d in DAY ] ++ ["+\n"] ++ [ if d = 1 then show_int(5,z) ++ " ||" else "" endif ++ show_int(4,let {var int: student = sum(s in STUDENT)(s*active[s,time(d,z)])} in if student > 0 then student else bool2int(z in teacher[d]) - 1 endif) ++ " |" ++ if d = num_days then "|\n" else "" endif | z in SLOT, d in DAY ] ++ [ " -------++"] ++ [ "-------+" | d in DAY ] ++ ["+\n"] ; Another option (sticking to the original model and easier to read) would be: ... array[STUDENT] of var TIME: start_time; include "disjunctive.mzn"; constraint disjunctive(start_time, lessonDuration); constraint forall(s in STUDENT) (start_time[s] in feasible_start_time[s]); var int: obj = sum(s in STUDENT, t in TIME where t >= start_time[s] /\ t <= start_time[s] + lessonDuration[s] - 1)(prio_time[s,t] + k*prioTeacher_time[t]); solve maximize obj; ...
Maple. Dsolve and functions
I have a differential equation that my program solves: p := dsolve({ic, sys}, numeric, method = rosenbrock); After solving we have the following: print(p(10)); [t = 10., alpha(t) = HFloat(0.031724302221312055), beta(t) = HFloat(0.00223975915581258)] I need use this alpha(t) and beta(t) as follows: a := t->exp( int(alpha(t)),x=0..t) ); b := t->exp( int(beta(t)),x=0..t) ) And draw a plot: odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20, thickness = 2, numpoints = 500, color = [red, blue]) The first thing that occurred to do so: p := dsolve({sys, ic}, numeric, method=rosenbrock); alpha := t->rhs(p(t)[2] ); beta := t->rhs(p(t)[3; a := t->exp( int(alphat)),x=0..t) ); b := t->exp( int(betat)),x=0..t) ); odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20, thickness = 2, numpoints = 500, color = [red, blue]) But the code does not work, and Yes, obviously, should act differently.
First, let's try to get your approach to work, with a few syntax and usage changes. You didn't supply the example's details, so I make up a system of differential equations sys and initial conditions ic so that your computational commands can be performed. restart: sys := diff(alpha(t),t) = -1/200*beta(t), diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2: ic := alpha(0)=0, beta(0)=-1: p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure): alphat := eval(alpha(t),p): betat := eval(beta(t),p): a := unapply( exp( Int(alphat , 0..t) ), t, numeric): b := unapply( exp( Int(betat , 0..t) ), t, numeric): evalf(a(20.0)), evalf(b(20.0)); -18 5.347592595, 3.102016550 10 st := time(): P := plots:-odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20, thickness = 2, numpoints = 50, color = [red, blue]): ( time() - st )*`seconds`; 16.770 seconds P; I used output=listprocedure so that I could assign the right procedures from solution p to alphat and betat. Those are more efficient to call many times, as opposed to your original which formed a sequence of values for each numeric t value and then had to pick off a certain operand. It's also more robust since its not sensitive to positions (which could change due to a new lexicographic ordering if you altered the names of your variables). The above took about 16 seconds on an Intel i7. That's not fast. One reason is that the numeric integrals are being computed to higher accuracy than is necessary for the plotting. So let's restart (to ensure fair timing) and recompute with relaxed tolerances on the numeric integrations done for a and b. restart: sys := diff(alpha(t),t) = -1/200*beta(t), diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2: ic := alpha(0)=0, beta(0)=-1: p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure): alphat := eval(alpha(t),p): betat := eval(beta(t),p): a := unapply( exp( Int(alphat , 0..t, epsilon=1e-5) ), t, numeric): b := unapply( exp( Int(betat , 0..t, epsilon=1e-5) ), t, numeric): evalf(a(20.0)), evalf(b(20.0)); -18 5.347592681, 3.102018090 10 st := time(): P := plots:-odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20, thickness = 2, numpoints = 50, color = [red, blue]): ( time() - st )*`seconds`; 0.921 seconds You can check that this gives a plot that appears the same. Now lets augment the example so that the numeric integrals are computed by dsolve,numeric itself. We can do that by using Calculus. In this way we are leaving it to the numeric ode solver to do its own error estimation, stepsize control, stiffness or singularity detection, etc. Note that the integrands alphat and betat are not functions for which we have explicit functions -- their accuracy is intimately tied to the numerical ode solving. This is not quite the same as simplistically using a numerical ode routine to replace a numeric quadrature routine for a problem with an integrand which we expect to be computed directly to any desired accuracy (including on either side of any singularity). restart: sys := diff(alpha(t),t) = -1/200*beta(t), diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2, diff(g(t),t) = alpha(t), diff(h(t),t) = beta(t): ic := alpha(0)=0, beta(0)=-1, g(0)=0, h(0)=0: p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure): alphat := eval(alpha(t),p): betat := eval(beta(t),p): gt := eval(g(t),p): ht := eval(h(t),p): exp(gt(20.0)), exp(ht(20.0)); -18 5.34759070530497, 3.10201330730572 10 st := time(): P := plots:-odeplot(p, [[t, exp(g(t))], [t, exp(h(t))]], 0 .. 20, thickness = 2, numpoints = 50, color = [red, blue]): ( time() - st )*`seconds`; 0.031 seconds P;