214 votes

Algorithme de largage de bombe

J'ai un n x m matrice composée d'entiers non négatifs. Par exemple:

2 3 4 7 1
1 5 2 6 2
4 3 4 2 1
2 1 2 4 1
3 1 3 4 1
2 1 4 3 2
6 9 1 6 4

"Lâchant une bombe" diminue d'une unité le nombre de la cellule cible et de huit de ses voisins, à moins de zéro.

x x x 
x X x
x x x

Qu'est ce qu'un algorithme qui permettrait de déterminer le nombre minimum de bombes nécessaires pour réduire toutes les cellules à zéro?

B Option (en Raison pour moi de ne pas être un lecteur attentif)

En fait, la première version de problème n'est pas celui que je cherche la réponse. Je n'ai pas de lire attentivement l'ensemble de la tâche, il y a des contraintes supplémentaires, nous disons:

Ce sujet de problème simple, lorsque la séquence dans la ligne doit être non-augmentation:

8 7 6 6 5 est possible de séquence d'entrée

7 8 5 5 2 n'est pas possible depuis le 7 -> 8 croissante dans une séquence.

Peut-être trouver réponse pour "plus facile" cas serait de les aider dans la recherche de solution pour la plus dure.

PS: je crois que lorsque l'on a plusieurs mêmes situations nécessitent un minimum de bombes pour effacer la ligne supérieure, vous choisissez l'une que l'utilisation de la plupart des bombes sur le "côté gauche" de la ligne. Encore une preuve que pourrait être correct?

37voto

psr Points 2009

Il y a un moyen de réduire ce chiffre à un simple sous-problème.

Il y a 2 parties, l'explication de l'algorithme, et la raison pour laquelle l'algorithme fournit une solution optimale. La première ne fera pas de sens sans la seconde, donc je vais démarrer avec le pourquoi.

Si vous pensez que des bombardements, le rectangle (assumer un grand rectangle - pas de bords cas encore) vous pouvez voir que la seule façon de réduire le rectangle creux de carrés sur le périmètre à 0 est de la bombe soit le périmètre ou à la bombe le rectangle creux de carrés à l'intérieur du périmètre. Je vais appeler le périmètre de la couche 1, et le rectangle à l'intérieur de la couche 2.

Une idée importante est qu'il n'y a pas de point de bombardement de la couche 1, parce que la "blast radius", vous obtenez de le faire est toujours contenu dans le rayon de l'explosion de un autre carré de la couche 2. Vous devriez être en mesure de facilement vous convaincre de cela.

Ainsi, on peut réduire le problème de trouver une manière optimale à la bombe à l'écart du périmètre, alors nous pouvons répéter que jusqu'à ce que toutes les places sont à 0.

Mais bien sûr, ce n'est pas toujours de trouver une solution optimale si il est possible de bombe loin du périmètre de moins en moins de façon optimale, mais en utilisant X bombes supplémentaires faire le problème de la réduction de la couche intérieure plus simple par >X bombes. Donc, si nous appelons le permiter de la couche, si l'on place un supplément de X bombes quelque part dans la couche 2 (juste à l'intérieur de la couche 1), peut-on réduire l'effort de la plus tard de bombardement à l'écart de la couche 2 de plus de X? En d'autres termes, nous devons prouver que nous pouvons être gourmand dans la réduction de l'extérieur de périmètre.

Mais, nous savons que nous pouvons être gourmand. Parce que pas de bombe dans la couche 2 peut être jamais plus efficace dans la réduction de la couche 2 à 0 que un stratégiquement placé la bombe dans la couche 3. Et pour la même raison qu'avant - il y a toujours une bombe on peut placer dans la couche 3 qui aura une incidence sur chaque carré de la couche 2 qui, une bombe placée dans la couche 2 peut. Donc, il peut jamais nous nuire d'être gourmand (dans ce sens de la gourmande).

Donc, tout ce que nous avons à faire est de trouver la manière optimale afin de réduire le permiter à 0 par les bombardements la prochaine couche intérieure.

Nous ne sommes jamais à mal par le premier bombardement aérien de l'angle à 0, car seul le coin de la couche interne peut l'atteindre, de sorte que nous n'avons pas vraiment le choix (et, tout à la bombe sur le périmètre qui peut atteindre le coin a un rayon de l'explosion contenue dans le rayon de l'explosion du coin de la couche interne).

Une fois que nous avons fait, les places sur le périmètre adjacent à l'0 angle ne peut être atteint par 2 carrés de la couche intérieure:

0       A       B

C       X       Y

D       Z

À ce stade, le périmètre est effectivement fermé 1 dimensions de la boucle, parce qu'une bombe va réduire de 3 cases adjacentes. Sauf pour certains étrangeté près des coins - X "hit" A,B,C,et D.

Maintenant, nous ne pouvons pas utiliser tout rayon de l'explosion astuces - la situation de chaque carré est symétrique, sauf pour ce qui est étrange des coins, et là encore pas de rayon de l'explosion est un sous-ensemble de l'autre. Notez que si c'était une ligne (comme le Colonel de Panique discute) au lieu d'une boucle fermée, la solution est triviale. Les points d'extrémité doit être réduite à 0, et il n'a jamais nuit à vous bombarder les points adjacents à la fin des points, parce que le rayon de l'explosion est un sur-ensemble. Une fois que vous avez fait votre point de terminaison de 0, vous avez encore un nouveau point de terminaison, sorte de répétition (jusqu'à ce que la ligne est 0).

Donc, si nous pouvons réduire de façon optimale une seule place dans la couche de 0, nous avons un algorithme (parce que nous avons coupé la boucle et ont maintenant une ligne droite avec des points de terminaison). Je crois que les bombardements autour de la place avec la valeur la plus basse (ce qui vous donne 2 options) tels que la valeur la plus élevée dans les 2 carrés de la valeur la plus faible est le minimum possible (vous pouvez diviser votre bombardements de gérer ce) sera optimal, mais je n'ai pas (encore?) avoir une preuve.

25voto

Colonel Panic Points 18390

Pólya dit "Si vous ne pouvez pas résoudre un problème, alors il ya un problème plus facile, vous pouvez résoudre: trouver."

L'évidence de plus simple problème est le 1-dimensions du problème (lorsque la grille est une seule ligne). Commençons par le plus simple des algorithmes goulûment bombardement de la plus grande cible. Quand est-ce mal?

Compte tenu de 1 1 1, l'algorithme glouton est indifférent à la il les premières bombes. Bien sûr, le centre de la cellule est mieux - il de zéros tous les trois cellules à la fois. Ceci suggère un nouvel algorithme A, "bombe à minimiser la somme restante". Quand est-ce que l'algorithme d'aller mal?

Compte tenu de 1 1 2 1 1, l'algorithme A est indifférent entre les bombardements de la 2e, 3e ou 4e cellules. Mais les bombardements de la 2ème cellule de quitter 0 0 1 1 1 est mieux que les bombardements de la 3ème cellule de quitter 1 0 1 0 1. Comment résoudre ce problème? Le problème avec les bombardements de la 3ème cellule est qu'il nous laisse travailler à gauche et à travailler pour le droit qui doit être fait séparément.

Comment parler de "bombe à minimiser la somme restante, mais de maximiser le minimum de la gauche (d'où on a bombardé), en plus du minimum pour le droit". Appelons cet algorithme B. Quand est-ce que l'algorithme d'aller mal?


Edit: Après avoir lu les commentaires, je suis d'accord beaucoup plus intéressante problème serait du à une dimension du problème a changé de sorte que les extrémités se rejoignent. Aimerais voir les progrès sur ce point.

12voto

Steven Xu Points 8025

J'ai dû arrêter à seulement une solution partielle à ce problème depuis que j'ai été hors du temps, mais nous espérons encore cette solution partielle fournit quelques indications sur une approche possible pour résoudre ce problème.

Lorsqu'ils sont confrontés à un problème difficile, je tiens à venir avec le plus simple des problèmes pour développer une intuition sur le problème de l'espace. Ici, la première étape j'ai pris était de réduire ce 2-D problème dans un 1-D de problème. Considérons une droite:

0 4 2 1 3 0 1

D'une manière ou d'une autre, vous savez que vous aurez besoin de la bombe à ou près de l' 4 spot 4 fois à le faire descendre à 0. Depuis la gauche de la tache est un nombre inférieur, il n'y a aucun avantage à les bombardements de l' 0 ou 4 sur le bombardement de l' 2. En fait, je crois (mais il leur manque une preuve rigoureuse) que le bombardement de l' 2 jusqu'à ce que l' 4 spot descend à 0 est au moins aussi bonne qu'une autre stratégie pour obtenir que l' 4 jusqu'à 0. On peut continuer vers le bas de la ligne de la gauche vers la droite dans une stratégie comme ceci:

index = 1
while index < line_length
  while number_at_index(index - 1) > 0
    bomb(index)
  end
  index++
end
# take care of the end of the line
while number_at_index(index - 1) > 0
  bomb(index - 1)
end

Un couple de l'échantillon bombardement de commandes:

0 4[2]1 3 0 1
0 3[1]0 3 0 1
0 2[0]0 3 0 1
0 1[0]0 3 0 1
0 0 0 0 3[0]1
0 0 0 0 2[0]0
0 0 0 0 1[0]0
0 0 0 0 0 0 0

4[2]1 3 2 1 5
3[1]0 3 2 1 5
2[0]0 3 2 1 5
1[0]0 3 2 1 5
0 0 0 3[2]1 5
0 0 0 2[1]0 5
0 0 0 1[0]0 5
0 0 0 0 0 0[5]
0 0 0 0 0 0[4]
0 0 0 0 0 0[3]
0 0 0 0 0 0[2]
0 0 0 0 0 0[1]
0 0 0 0 0 0 0

L'idée de départ avec un nombre qui doit aller vers le bas d'une manière ou d'une autre est un attrayant, car il devient tout à coup accessible pour trouver une solution qui, comme certains le prétendent d'être au moins aussi bonne que toutes les autres solutions.

La prochaine étape dans la complexité où cette recherche d' au moins aussi bonne est encore possible est sur le bord de la carte. Il est clair pour moi qu'il n'y a aucune stricte des prestations à la bombe contre le bord externe; vous êtes mieux de bombardement de la place d'en obtenir trois autres espaces de libre. Compte tenu de cela, nous pouvons dire que le bombardement de l'anneau à l'intérieur de la bordure est au moins aussi bon que le bombardement du bord. En outre, on peut combiner cela avec l'intuition que le bombardement de la droite à l'intérieur de la bordure est en fait la seule façon d'obtenir de bord espaces à 0. Même plus, il est carrément simple pour déterminer la stratégie optimale (en ce qu'elle est au moins aussi bonne que n'importe quelle autre stratégie) pour obtenir l'angle des nombres jusqu'à 0. Nous avons mis tous ensemble et que vous pouvez obtenir beaucoup plus près d'une solution dans la 2-D de l'espace.

Compte tenu de l'observation au sujet de pièces de coin, nous pouvons dire que nous savons que la stratégie optimale pour passer d'une planche de départ à un conseil d'administration avec des zéros sur tous les angles. Ceci est un exemple de ce type de conseil (j'ai emprunté les numéros à partir du linéaire de deux planches ci-dessus). J'ai étiqueté certains espaces différemment, et je vais vous expliquer pourquoi.

0 4 2 1 3 0 1 0
4 x x x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

On remarquera à la rangée du haut vraiment ressemble étroitement linéaires exemple que nous avons vu plus tôt. En rappelant que notre observation précédente selon laquelle la meilleure façon d'obtenir la rangée supérieure à 0 est de la bombe de la deuxième rangée (de l' x de la rangée). Il n'existe aucun moyen pour effacer la ligne d'en haut par les bombardements tout de l' y lignes et aucun avantage supplémentaire de bombardement de la ligne du haut, au cours de bombardements de l'espace correspondant sur l' x ligne.

On pourrait appliquer le linéaire de la stratégie à partir de ci-dessus (à bombarder les espaces correspondants sur l' x rangée), au sujet de nous-mêmes seulement avec le haut de la ligne et rien d'autre. Ce serait quelque chose comme ceci:

0 4 2 1 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 3 1 0 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 2 0 0 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 1 0 0 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 0 0 0 3 0 1 0
4 x x x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

Le défaut de cette approche est particulièrement évidente dans les deux derniers attentats à la bombe. Il est clair, étant donné que la seule bombe de sites qui permettent de réduire l' 4 figure dans la première colonne de la deuxième ligne sont le premier x et de la y. Les deux derniers attentats à la bombe sont nettement inférieures à juste bombardements de la première x, ce qui aurait fait exactement la même (en ce qui concerne la première place dans la rangée du haut, que nous n'avons pas d'autre moyen de compensation). Depuis, nous avons démontré que notre stratégie actuelle n'est pas optimale, une modification de la stratégie est clairement nécessaire.

À ce stade, je peux prendre un pas en arrière vers le bas dans la complexité et de se concentrer seulement un un coin. Considérons celui-ci:

0 4 2 1
4 x y a
2 z . .
1 b . .

Il est clair que la seule façon d'obtenir les espaces avec des 4 vers le bas à zéro sont à la bombe contre une combinaison d' x, y, et z. Avec quelques acrobaties dans mon esprit, je suis assez sûr que la solution optimale est de la bombe x trois fois et ensuite, a alors b. Maintenant c'est une question de comprendre comment je suis arrivé à cette solution et si elle révèle toute l'intuition que nous pouvons utiliser à même de résoudre ce problème local. Je remarque qu'il n'y a pas de bombardements de l' y et z espaces. Essaye de trouver un coin où les bombardements de ces espaces de sens que donne un coin qui ressemble à ceci:

0 4 2 5 0
4 x y a .
2 z . . .
5 b . . .
0 . . . .

Pour cela, il est clair pour moi que la solution optimale est de la bombe y 5 fois et z 5 fois. Nous allons aller un peu plus loin.

0 4 2 5 6 0 0
4 x y a . . .
2 z . . . . .
5 b . . . . .
6 . . . . . .
0 . . . . . .
0 . . . . . .

Ici, il se sent de la même façon intuitive que la solution optimale est de la bombe a et b 6 fois et ensuite, x 4 fois.

Maintenant, il devient un jeu de la façon de transformer ces intuitions dans les principes que nous pouvons construire.

Espérons-le, d'être poursuivi!

11voto

Evgeny Kluev Points 16685

Pour la mise à jour de la question d'un simple algorithme glouton donne un résultat optimal.

Déposez Un[0,0] bombes à la cellule[1,1], puis déposez Une[1,0] bombes à la cellule[2,1], et la poursuite de ce processus vers le bas. Pour nettoyer le coin en bas à gauche, déposer max(A[N-1,0], A[N-2,0], A[N-3,0]) bombes à la cellule[N-2,1]. Ce sera complètement nettoyer les 3 premières colonnes.

Avec la même approche, nettoyage des colonnes 3,4,5, puis les colonnes 6,7,8, etc.

Malheureusement, cela n'aide pas à trouver de solution pour le problème original.


"De gros" problème (sans "nonicreasing" contrainte) peut être prouvée pour être NP-difficile. Voici l'esquisse de la preuve.

Supposons que nous avons un graphe planaire de degré au plus 3. Nous allons trouver le minimum vertex cover de ce graphe. Selon l'article de Wikipedia à ce problème est NP-difficile pour les graphes planaires de degré au plus 3. Cela pourrait être prouvée par la réduction de Planes 3SAT. Et la dureté de la Planaire 3SAT - par la réduction de 3SAT. Ces deux épreuves sont présentées dans les dernières conférences en "Algorithmique Limites Inférieures" par le prof. Erik Demaine (cours 7 et 9).

Si nous nous sommes séparés quelques bords de l'original graphique (graphique de gauche sur le schéma), chacune avec le même nombre de nœuds supplémentaires, le graphe obtenu (graphique de droite sur le schéma) devraient avoir exactement le même minimum vertex cover d'origine pour les sommets. Cette transformation permet d'aligner graphe de sommets à l'arbitraire des positions sur la grille.

enter image description here

Si nous plaçons graphique uniquement des sommets de même les lignes et les colonnes (de telle sorte que deux arêtes incident à un sommet forme un angle aigu), insérer "" partout où il y a un bord, et insérer des "zéros" à d'autres positions sur la grille, on peut utiliser n'importe quelle solution pour le problème d'origine pour trouver le minimum vertex cover.

9voto

SidR Points 1002

Ce serait une approche gourmande:

  1. Calculer un "score" de la matrice d'ordre n X m, où le score[i][j] est le total des déductions de points dans la matrice si la position (i,j) est bombardée. (Max score d'un point de 9 min score est de 0)

  2. Déplacement de la ligne sage, et trouver la première position avec un score élevé (dire (i,j)).

  3. De la bombe (i,j). Augmentation de la bombe comte.

  4. Si tous les éléments de la matrice d'origine ne sont pas à zéro, puis goto 1.

J'ai des doutes que c'est la solution optimale.

Edit:

L'approche Gourmande que j'ai posté ci-dessus, alors qu'il travaille, plus probablement, ne nous donne pas la solution optimale. Alors j'ai pensé que devrait ajouter certains éléments de la DP.

Je pense que nous pouvons convenir que, à tout moment, l'un des postes les plus élevés "note" (note[i][j] = total des déductions de points si (i,j) est bombardée) doit être ciblée. Partant de cette hypothèse, voici la nouvelle approche:

NumOfBombs(M): (retourne le nombre minimum d'attentats à la bombe obligatoire)

  1. Étant donné une Matrice M d'ordre n X m. Si tous les éléments de M sont égaux à zéro, puis retour à 0.

  2. Calculer le "score" de la matrice M.

    Laissez le k distincts positions P1,P2,...Pk (1 <= k <= n*m), les positions de M avec les scores les plus élevés.

  3. retour (1 + min( NumOfBombs(M1), NumOfBombs(M2), ..., NumOfBombs(Mk) ) )

    où M1,M2,...,Mk sont les matrices résultantes si nous bombarder les positions P1, P2, ..., Pk, respectivement.

Aussi, si nous voulons l'ordre des positions de nuke en plus de cela, nous devons garder une trace des résultats de "min".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X