File: mineInit.sci

package info (click to toggle)
scilab 2.4-1
  • links: PTS
  • area: non-free
  • in suites: potato, slink
  • size: 55,196 kB
  • ctags: 38,019
  • sloc: ansic: 231,970; fortran: 148,976; tcl: 7,099; makefile: 4,585; sh: 2,978; csh: 154; cpp: 101; asm: 39; sed: 5
file content (134 lines) | stat: -rw-r--r-- 4,095 bytes parent folder | download | duplicates (2)
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
function []=mineInit()
// Macro qui initialise les donnees du
// td3
//!
// Copyright INRIA
n1=30
n2=40;
te=n2/2;
xe=n1/2;
k0=1;
kc=0.01;
[n1,n2,te,xe,k0,kc]=resume(...
        n1,n2,te,xe,k0,kc);

function [cout,feed]=mine(n1,n2,uvect)
//[cout,feed]=mine(n1,n2,uvect)
// extraction optimale d'un minerai d'une mine a ciel ouvert
// en avancant progressivement (k=1,2,...,n2) et en
// prelevant a l'abcisse k+1 la tranche de profondeur x(k+1)
// par une commande u a partir de la profondeur x(k)
// a l'abcisse k.
//
// la resolution du probleme se fait par programmation dynamique
// en calculant la commande optimale maximisant le critere :
//
//   -- n2-1
//   \
//   /        f(x(k),k) + V_F(x,n2)
//   -- k=1
//  avec : x(k+1)=x(k) + u
//  x(k) est la profondeur de la mine a l'abcisse k (x=1
//      est le niveau du sol)
// la fonction gain instantane f(i,k) represente le benefice
//      si on creuse la profondeur i a l'abcisse k
//  V_F(i,n2) est un cout final destine a forcer l'etat final
//       a valoir 1 (pour sortir de la mine ...)
//       V_F(i,n2) vaut -10000 en tout les points i\ne1 et 0
//       pour i=1
//
// le programme mine necessite de connaitre
//    n1    : l'etat est discretise en n1 points
//	      1 c'est l'air 
//	      2:n1+1 du sol au fond 
//	      n1+2 zone interdite
//    n2    : nombre d'etapes 
//    uvect : vecteur ligne des valeurs discretes que peut
//          prendre u (3 valeurs, on monte, on descend ou on avance)
// et le programme mine retourne alors deux matrices
//    cout(n1,n2) : valeurs de la fonction de Bellman
//    feed(n1,n2) : valeurs de la commande a appliquer
//          lorsque l'etat varie de 1 a n1 et
//          l'etape de 1 a n2.
//    n1    : l'etat est discretise en n1 points
//	      on rajoute dans le calcul deux couches fictive 
//	      en 1 l'air en n1+2 le fond de la mine 
//	      1 c'est l'air 
//	      2:n1+1 du sol au fond 
//	      n1+2 zone interdite
//!
usize=prod(size(uvect))
xgr=1:(n1+2)
// tableau ou l'on stocke la fonction de Bellman
cout=0*ones(n1+2,n2);
// tableau ou l'on stocke le feedback u(x,t)
feed=0*ones(n1,n2);
// calul de la fonction de Bellman au  temps final
penal=10000;
// Le cout final est le cout au point de sortie de la zone d'extraction 
// on veut evidement que ce point de sortie soit le sol 
// le cout est donc 0 au niveau du sol et -inf ailleurs 
cout(:,n2)=-penal*ones(n1+2,1);
cout(2,n2)=0;
// calcul retrograde de la fonction de Bellman et
// du controle optimal au temps temp par l'equation de Bellman
for temp=n2:-1:2,
  loc=list();
  for i=1:usize,
    newx=mini(maxi(xgr+uvect(i)*ones(xgr),1*ones(xgr)),(n1+2)*ones(xgr)),
    loc(i)=cout(newx,temp)+ff_o(xgr,temp-1),
  end;
  [mm,kk]=maxi(loc),
  cout(xgr,temp-1)=mm;
  cout(1,temp-1)=-penal;
  cout(n1+2,temp-1)=-penal;
  feed(xgr,temp-1)=uvect(kk)';
end

function [y]=ff_o(x,t)
//[y]=ff_o(x,t)
// gain instantane apparaissant dans le critere du
// programme mine.
//
// pour des raisons techniques, l'argument x doit
// etre un vecteur colonne et donc egalement la sortie y.
// en sortie y=[ ff_0(x(1),t),...ff_o(x(n),t)];
//!
xxloc=ones(x);
y=k0*(1-(t-te)**2/(n2**2))*xxloc - (x-xe*xxloc)**2/(n1**2) -kc*(x-1*xxloc)
y=y';
y(1:2)=[0;0]

function []=showcost(n1,n2)
//[]=showcost(n1,n2)
// Montre en 3d la fonction de gain instantanee (ff)
// x: profondeur (n1)
// y: abscisse  (n2)
// en z : valeur de ff_o(x,t)
//!
[lhs,rhs]=argn(0)
m=[];
for i=1:n2,m=[m,ff_o(1:n1,i)],end
contour(1:n2,1:n1,m',10,0,0,' ',[2,2,0])

function []=trajopt(feed)
//[]=trajopt(feed)
// feed est la matrice de feedback calculee par mine
// trajopt calcule et dessine la trajectoire et le controle
// optimaux pour un point de depart (1,1)
//!
[n1,n2]=size(feed)
xopt=0*ones(1,n2)
uopt=0*ones(1,n2+1)
xopt(1)=2;
for i=2:(n2+1),xopt(i)=feed(xopt(i-1),i-1)+xopt(i-1),
             uopt(i-1)=feed(xopt(i-1),i-1),end
plot2d2("gnn",[1:(n2+1)]',[-xopt]',[2],"111",...
       "trajectoire optimale",...
       [1,-n1,n2+1,2]);
plot2d2("gnn",[1:(n2)]',uopt(1:n2)',[1,-4],"111",...
       "commande optimale",...
       [1,-n1,n2+1,2]);