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;