Mathematica 186 (gourmand) et 224 (toutes combinaisons)
Solution gourmande
t=MorphologicalTransform;n@w_:=Flatten@w~Count~1
p_~w~q_:=n[p~t~Max]==n[q~t~Max]
g@m_:=Module[{l=m~Position~1,r,d=m},While[l!={},If[w[m,r=ReplacePart[d,#-> 0]&
[l[[1]]]],d=r];l=Rest@l];n@m-n@d]
Cela éteint les lumières superflues une par une. Si la couverture lumineuse n'est pas diminuée lorsque la lumière s'éteint, cette lumière peut être éliminée. L'approche gourmande est très rapide et peut facilement gérer des matrices de 15x15 et bien plus grandes (voir ci-dessous). Il renvoie une seule solution, mais on ne sait pas si c'est optimal ou non. Les deux approches, dans les versions golfées, renvoient le nombre de lumières inutilisées. Les approches non golfées affichent également les grilles, comme ci-dessous.
Avant:

Après:

Solutions optimales utilisant toutes les combinaisons de lumières (224 caractères)
Merci à @ Clément.
Version non golfée utilisant toutes les combinaisons de lumières
fLa fonction de transformation morphologique utilisée dans les sameCoverageQgâteries comme éclairé (valeur = 1 au lieu de zéro) le carré 3 x3 dans lequel chaque lumière réside. Lorsqu'une lumière est proche du bord de la ferme, seuls les carrés (moins de 9) à l'intérieur des limites de la ferme est comptée. Il n'y a pas de comptage excessif; un carré éclairé par plus d'une lampe est simplement allumé.Le programme éteint chaque lumière et vérifie si la couverture d'éclairage globale de la ferme est réduite.Si ce n'est pas le cas, cette lumière est éliminée.
nOnes[w_]:=Count[Flatten@w,1]
sameCoverageQ[m1_,m2_]:=nOnes[MorphologicalTransform[m1,Max]]==
nOnes[MorphologicalTransform[m2,Max]]
(*draws a grid with light bulbs *)
h[m_]:=Grid[m/.{1-> Style[\[LightBulb],24],0-> ""},Frame-> All,ItemSize->{1,1.5}]
c[m1_]:=GatherBy[Cases[{nOnes[MorphologicalTransform[ReplacePart[Array[0&,Dimensions[m1]],
#/.{{j_Integer,k_}:> {j,k}-> 1}],Max]],#,Length@#}&/@(Rest@Subsets[Position[m1,1]]),
{nOnes[MorphologicalTransform[m1,Max]],_,_}],Last][[1,All,2]]
nOnes[matrix]compte le nombre de cellules marquées. Il est utilisé pour compter les lumières et aussi pour compter les cellules allumées
sameCoverageQ[mat1, mat2] teste si les cellules allumées dans mat1 sont égales au nombre de cellules allumées dans mat2.MorphologicalTransform [[mat] prend une matrice de lumières et renvoie une matrice` des cellules qu'elles éclairent.
c[m1]prend toutes les combinaisons de lumières de m1 et les teste pour la couverture. Parmi ceux qui ont la couverture maximale, il sélectionne ceux qui ont le moins d'ampoules. Chacun d'eux est une solution optimale.
Exemple 1:
Une configuration 6x6
(*all the lights *)
m=Array[RandomInteger[4]&,{6,6}]/.{2-> 0,3->0,4->0}
h[m]

Toutes les solutions optimales.
(*subsets of lights that provide full coverage *)
h/@(ReplacePart[Array[0&,Dimensions[m]],#/.{{j_Integer,k_}:> {j,k}-> 1}]&/@(c[m]))

Version golfée utilisant toutes les combinaisons de lumières.
Cette version calcule le nombre de lumières inutilisées. Il n'affiche pas les grilles.
c renvoie le nombre de lumières inutilisées.
n@w_:=Flatten@w~Count~1;t=MorphologicalTransform;
c@r_:=n@m-GatherBy[Cases[{n@t[ReplacePart[Array[0 &,Dimensions[r]],#
/.{{j_Integer,k_}:> {j,k}-> 1}],Max],#,Length@#}&/@(Rest@Subsets[r~Position~1]),
{n[r~t~Max],_,_}],Last][[1,1,3]]
n[matrix]compte le nombre de cellules marquées. Il est utilisé pour compter les lumières et aussi pour compter les cellules allumées
s[mat1, mat2] teste si les cellules allumées dans mat1 sont égales au nombre de cellules allumées dans mat2.t [[mat] prend une matrice de lumières et renvoie une matrice` des cellules qu'elles éclairent.
c[j]prend toutes les combinaisons de lumières de j et les teste pour la couverture. Parmi ceux qui ont la couverture maximale, il sélectionne ceux qui ont le moins d'ampoules. Chacun d'eux est une solution optimale.
Exemple 2
m=Array[RandomInteger[4]&,{6,6}]/.{2-> 0,3->0,4->0};
m//Grid

Deux lumières peuvent être enregistrées tout en ayant la même couverture d'éclairage. cm]
2