Page 1 of 1

Problème en LUA

Unread postPosted: 02 Oct 2017, 14:37
by red17
Bonjour,

J'essai de programmer l'algorithme du simplexe.
Mais je n'y arrive pas...

Mon code :
Code: Select all
function maxima(t)
    n = #t
   m = 0
   p = 0
   for i=1,n-1 do
       m = math.max(t[i],t[i+1])
   end
   for i=1,n do
       if m == t[i] then
          p=i
      end
   end
   t0 = {m,p}
   return t0
end

function count(M)
    n={}
   k=0
   for j=1,#M[1] do
       for i=1,#M do
           if M[i][j]==1 then
                k=k+1
            end            
      end
      n[j]=k
      k=0
   end
   N=0
   for p=1,#n do
       if n[p]==1 then
          N=N+1
      end
   end
   return N
end

Simplex = function(A, i0, Ci, Delta_j0, X, Z)
    Delta_j = Delta_j0
   
   O=0
   while O < #A[1] do
        j = maxima(Delta_j)[2]
       x={}
        for i=1,#X do
           x[i]=X[i]/A[i][j]
       end
       i = maxima(x)[2]
        pivot = A[i][j]
   
       for k=1,#X do
           X[k]=X[k]-A[k][j]*X[i]/A[i][j]
          for l=1,#X[1] do
              A[k][l] = A[k][l] - A[k][j]*A[i][l]/A[i][j]
          end
       end
       I=i
       Z = Z+X[i]*Delta_j[j]/A[i][j]
       Delta = Delta_j
       Ci[I]=Delta[j]
       for r=1,#i0 do
           if i0[r]==i then
              i0[r]=i
          end
       end
       for p=1,#Delta_j do
           Delta_j[p] = Delta_j0[p]
          for s=1,#Ci do
              Delta_j[p] = Delta_j[p] - Ci[s]*A[s][p]
          end
       end
      O=O+1
   end
   return {A, i0, Ci, Delta_j0, X, Z}
end

function Matrix(A)
    n=#A
   p=#A[1]
   txt = {}
   t = "["
   for i=1,n do
       for j=1,p do
          txt[i]=tostring(A[i][j]).." "
      end
      t=t.."["..(txt[i]).."]"
   end
   return t
end
function Ligne(C)
    n=#C
   txt = ""
   for i=1,n do
       txt = txt..tostring(C[i]).." "
   end
   return txt
end

function on.create()
   var.monitor("A")
   var.monitor("I")
   var.monitor("C")
   var.monitor("D")
   var.monitor("X")
   var.monitor("Z")
end
function on.varChange(varlist)
   -- On provoque une reactualisation de la fenetre
   platform.window:invalidate()
end

function on.paint(gc)
   local wh, ww, n, x
   -- nombre de pixels (hauteur et largeur)
   wh = platform.window:height()
   ww = platform.window:width()

   -- affichage d'un trait de separation
   gc:setPen("medium", "smooth")
   gc:drawLine(0, 60, ww, 60)

   -- affichage de la taille de la fenetre en bas de l'ecran
   -- il s'agit juste d'un exemple !
   gc:setColorRGB(200, 200, 200)
   x = gc:drawString(wh, 10, wh - 10, "bottom")
   gc:drawString(ww, x + 10, wh - 10, "bottom")

   -- affichage de n!
   A = var.recall("A")
   I = var.recall("I")
   C = var.recall("C")
   D = var.recall("D")
   X = var.recall("X")
   Z = var.recall("Z")
   
   S = Simplexe(A,I,C,D,X,Z)
   
   gc:setColorRGB(0, 0, 255)
   gc:setFont("sansserif" , "b", 20)
   for i=1,6 do
       x = gc:drawString((i==1 and Matrix(S[i]) or Ligne(S[i])), 10+x*10, 10, "top")
   end
end


L'erreur que j'obtiens :
20: attempt to index local 'M' (a nil value)

J'ai l'impression que l'interpréteur ne sait pas que M est une variable locale passée en paramètre.. Normal qu'elle soit de valeur nulle, non ? Je ne vois pas d'erreur.

Quelqu'un peut m'aider ? Je suis assez pressé et désespéré lol :(

Merci d'avance

Re: Problème en LUA

Unread postPosted: 02 Oct 2017, 17:31
by Adriweb
Ben non, l'interpréteur a raison :)
Un argument d'une fonction, si tu ne le passes pas en paramètre depuis l'appelant, aura une valeur nil.
Dans ton code, d'ailleurs, je ne te vois pas appeler la fonction count. Puisqu'apparemment c'est censé etre une table, il faudra donc que tu l'appelles avec une table.

Mais par contre, on.create n'existe plus depuis longtemps. Regarde plutôt on.construction.
Sinon, rappeler les variable depuis le paint et lancer Simplexe(), c'est pas bien, ca veut dire que ton algo va etre appelé à chaque fois que tu bouges ta souris par exemple, ou appuies sur un bouton.
Vu que tu utilise le on.varChange, ce serait bien mieux de le mettre la dedans, suivi d'un platform.window:invalidate()

(et au passage, c'est pas bien d'utiliser autant de globales, tu peux localiser pas mal de choses, ca ira plus vite :))

(et au passage aussi, le on.paint est appelé avec d'autres paramètres après gc : x, y, w, h - plus besoin de demander width et height juste apres !)