31 votes

Étant donné deux lignes sur un plan, comment trouver les points entiers les plus proches de leur intersection ?

Je ne peux pas le résoudre :

On vous donne 8 nombres entiers :

  • A, B, C représentant une ligne sur un plan avec l'équation A x + B y = C
  • a, b, c représentant une autre ligne
  • x, y représentant un point sur un plan

Les deux lignes ne sont pas parallèles, il faut donc diviser le plan en 4 morceaux. Le point (x, y) se trouve à l'intérieur d'un de ces morceaux.

Problème :
Écrivez un algorithme rapide qui trouvera un point avec des coordonnées entières dans le même morceau que (x,y) qui est le plus proche du point de croisement des deux lignes données.

Note :
Ce n'est pas un devoir, c'est de l'ancien. Euler -que je ne sais absolument pas comment aborder.

Mise à jour : Vous pouvez supposer que les 8 nombres en entrée sont des entiers signés de 32 bits. Mais vous ne pouvez pas supposer que la solution sera de 32 bits.

Mise à jour 2 : Le cas difficile - lorsque les lignes sont presque parallèles - est le cœur du problème.

Mise à jour 3 : L'auteur du problème affirme que la solution est un algorithme linéaire O(n). Où n est la taille de l'entrée (en bits). C'est-à-dire : n = log(A) + log(B) + ... + log(y)
Mais je ne peux toujours pas le résoudre.

Veuillez indiquer les complexités des algorithmes publiés (même si elles sont exponentielles).

5 votes

Ce n'est PAS un problème du projet Euler - c'est un problème de type Euler.

0 votes

Bon point, @Lew. Quoi qu'il en soit, merci pour ce titre plus spécifique.

1 votes

@All : J'ai rétrogradé toutes les réponses parce qu'elles ne résolvent pas le problème de manière rapide. Je suppose que cette tâche nécessite des connaissances particulières et appartient vraiment à mathoverflow.

9voto

Pratik Deoghare Points 9766

texte alternatif http://imagebin.ca/img/yhFOHb.png

Diagramme

Après avoir trouvé l'intersection des lignes L1:Ax+By=C y L2:ax+by=c c'est-à-dire le point A(x1,y1) .

Définir deux autres lignes y = ceil(y1) y y = floor(y1) parallèle à X-axis et trouver leur intersection avec L1 y L2 i.e. Points B(x2,y2) y C(x3,y3) .

Alors le point dont vous avez besoin est D o E celui qui est le plus proche du point A . Une procédure similaire s'applique aux autres parties du plan.

D ( ceil(x2), ceil(y1)  )
E ( ceil(x3), floor(y1) )

1 votes

Et si D et E ne sont pas dans le segment où se trouve X ? Et si, à la prochaine itération de ce que vous proposez, ces points sont également hors du segment ?

2 votes

Ce sont les quatre points entiers les plus proches de l'intersection. Le cas qui fait de cette question un défi est celui où aucun de ces quatre points ne se trouve dans le morceau spécifié. Cela se produit lorsque les deux lignes sont très proches de la parallèle, se rencontrant à un angle très très petit. La solution peut se trouver à des millions d'unités de l'intersection.

1 votes

@Pavel Shved, segment ? J'ai montré des segments dans la dia. mais je veux dire des lignes. Elles vont jusqu'à l'infini.

7voto

Eric Burnett Points 1122

Ce problème entre dans la catégorie des Optimisation convexe entière .

Nous présentons ici une façon mathématique d'aborder le problème. Je ne m'attends pas à ce que vous l'utilisiez réellement - beaucoup de techniques compliquées sont nécessaires, et d'autres approches algorithmiques (comme la "recherche" du point approprié) feront probablement l'affaire. Cependant, certains ont exprimé leur intérêt pour la "vraie" solution, alors la voici.

Il peut être résolu en trois étapes :

  1. Tout d'abord, déterminez de quel côté de chaque ligne se trouvera la réponse, comme l'illustre la réponse de TheMachineCharmer.
  2. Une fois que cela est connu, le problème peut être réécrit comme un problème d'optimisation convexe (cf. Wikipedia pour plus de détails). La fonction à optimiser est la minimisation de (x - x0)^2 + (y - y0)^2, avec x0 et y0 les coordonnées de l'intersection des deux lignes. Les deux lignes deviennent chacune une inégalité linéaire, par exemple "x+y >= 0", formant ensemble la région convexe dans laquelle la réponse peut être trouvée. Je noterai que la solution sera (x=x0, y=y0) - ce dont vous avez besoin à ce stade, c'est d'une manière d'exprimer le problème, analogue à un tableau de faisabilité pour le processus de la méthode simplex .
  3. Troisièmement, une solution entière peut être trouvée en ajoutant de manière répétée coupe pour contraindre davantage la région réalisable jusqu'à ce que la solution du problème d'optimisation convexe soit intégrale. Cette étape peut prendre beaucoup d'itérations dans le cas général, mais en regardant le problème présenté, et en particulier sa nature 2D, je pense qu'il sera résolu avec au plus deux coupes.

1 votes

Dire que le problème de l'optimisation convexe entière est une généralisation aussi bonne que de dire que c'est un problème de recherche. C'est trop large.

0 votes

Je le modifierai volontiers si quelqu'un peut nommer une catégorie plus spécifique dans laquelle il s'inscrit. Il ne s'agit certainement pas d'une ILP comme le prétendent de nombreuses personnes, je tenais donc à être clair. Notez également que les problèmes d'optimisation convexe nécessitent que la fonction objectif soit convexe (c'est-à-dire que pour un z donné, les points où f(x, y) <= z est un ensemble convexe) et pas seulement la région réalisable, donc ce n'est peut-être pas aussi large que vous le pensez.

0 votes

La partie "ajouter quelques coupes" est vraiment, vraiment vague. Bien sûr, vous pouvez peut-être trouver la solution en ajoutant deux coupes dans un certain sens, mais, si c'est le cas, trouver les spécifications de ces coupes devient équivalent au problème original, et vous n'avez pas vraiment dit quelque chose.

5voto

Eric Bainville Points 5300

Je montre ici comment une instance "difficile" de ce problème peut être résolue. Je pense que cette méthode peut être généralisée. J'ai mis une autre instance plus simple dans les commentaires de l'article original.

Considérez les deux lignes :

10000019 * X - 10000015 * Y + 909093 >= 0    (L1)
-10000022 * X + 10000018 * Y + 1428574 >= 0  (L2)
A = 10000019, B = -10000015, C = -909093

Le point d'intersection est H :

Hx = -5844176948071/3, Hy = -5844179285738/3

Pour un point M(X,Y), la distance au carré HM^2 est :

HM^2 = (9*X^2+35065061688426*X
    +68308835724213587680825685
    +9*Y^2+35065075714428*Y)/9

g = pgcd(A,B) = 1 : l'équation de L1 A*X+B*Y+909093 peut prendre n'importe quelle valeur entière.

Les coefficients de déviation, U=2500004 et V=2500005, sont vérifiés :

A * U + B * V = 1

Nous réécrivons maintenant le problème dans la base "double" (K,T) définie par :

X = T*U - K*B
Y = T*V + K*A

Après substitution, on obtient :

T+909093 >= 0
2*T+12*K+1428574 >= 0
minimize 112500405000369*T^2
   +900003150002790*T*K
   +1800006120005274*K^2
   +175325659092760325844*T
   +701302566240903900522*K
   +Constant

Après une nouvelle traduction (d'abord sur T, puis sur K pour minimiser la constante de la deuxième équation), T=T1-909093, K=K1+32468 :

T1 >= 0
2*T1+4+12*K1 >= 0
minimize 112500405000369*T1^2
    +300001050000930*T1
    +900003150002790*T1*K1
    +1200004080003516*K1
    +1800006120005274*K1^2
    +Constant

L'algorithme que j'ai proposé consiste à boucler sur T1. En fait, nous n'avons pas besoin de boucle ici, puisque le meilleur résultat est donné par T1=K1=0, correspondant à :

X = -1948055649352, Y = -1948056428573

Mon message initial ci-dessous.

Voici une autre idée d'algorithme. Elle peut fonctionner, mais je ne l'ai pas mise en oeuvre...

Avec un changement de signe approprié pour correspondre à la position de (x,y), le problème peut être écrit :

A*X+B*Y>=C  (line D)
a*X+b*Y>=c  (line d)
minimize the distance between M(X,Y) and H, the intersection point
A*b != a*B (intersection is defined)
A,B,C,a,b,c,X,Y all integers

L'ensemble de toutes les valeurs atteintes par (A X+B Y) est l'ensemble de tous les multiples de g=gcd(A,B), et il existe des entiers (u,v) tels que A u+B v=g (théorème de Bezout). A partir d'un point de coordonnées entières (X0,Y0), tous les points de coordonnées entières et de même valeur de A X+B Y sont (X0-K B/g,Y0+K A/g), pour tous les entiers K.

Pour résoudre le problème, on peut boucler sur des lignes parallèles à D à distance croissante de H, et contenant des points de coordonnées entières.

  1. Calculez g,u,v, et H (les coordonnées de H ne sont probablement pas nécessaires, nous avons seulement besoin des coefficients de la forme quadratique correspondant à la distance).

  2. T0 = ceil(C/g)

  3. Boucle de T = T0

    a. Trouvez K le plus petit (ou le plus grand, selon le signe de a B-b A) entier vérifiant a*(T u-K B/g)+b*(T v+K A/g)>=c

    b. Point de maintien (T u-K B/g,T v+K A/g) si elle est plus proche de H

    c. Sortir de la boucle lorsque (T-T0) correspond à une distance de D plus grande que le meilleur résultat obtenu jusqu'à présent, sinon continuer avec T+=1

0 votes

Fait Cst moyenne constant ?. Si c'est le cas, il est peut-être préférable de l'écrire de cette façon.

0 votes

Génial. Pouvez-vous expliquer l'astuce de la "double" base ? Qu'est-ce que vous accomplissez ? S'agit-il d'obtenir une équation finale dans K1 et K2 avec des coefficients assez faibles ? Est-ce une technique bien connue, et dans quel domaine ? Et pensez-vous toujours que, dans le cas général, vous devez faire une boucle ? Oh, et quel outil utilisez-vous pour résoudre vos équations et vos grands nombres ?

0 votes

Les formulations "duales" expriment généralement les inconnues comme une combinaison linéaire des contraintes. Ici, cela reviendrait à exprimer (X,Y) comme une combinaison de (A,B,C) et (a,b,c). Comme il s'agit d'entiers, cela passe mieux en utilisant ce "pseudo-double". Notez que tout ceci peut être trivial pour les utilisateurs réguliers de bases Z et de treillis (je ne sais pas).

4voto

user51568 Points 1519

J'ai fait des recherches sur ce problème dans le passé (à la fois parce que c'est amusant et parce que j'ai rencontré quelque chose de similaire dans un endroit où je travaillais).

A ma connaissance, il n'existe pas d'algorithme efficace (FPTIME) pour ce problème.

La seule solution connue (pour moi) est d'énumérer les coordonnées entières (en commençant autour de l'intersection) jusqu'à ce que vous trouviez celle que vous voulez. Ceci n'est bien sûr pas du tout efficace lorsque l'angle entre les deux lignes est très petit. Vous pouvez faire un peu d'élagage pour améliorer l'efficacité et, lorsque la pente est petite, l'efficacité est décente.

Une généralisation de cette méthode (ILP - integer linear programming) est connue pour être NP-complexe.

0 votes

Comme je l'ai noté dans la réponse d'Alan, ce problème n'est pas linéaire (minimiser x^2 + y^2), donc ce n'est pas strictement ILP, mais plutôt Integer Convex Optimization. Mais cela aussi est NP-complet, puisque ILP est un cas spécial.

5 votes

Le fait que la généralisation soit NP-complète n'implique pas que le problème original soit NP-complet.

0 votes

@Eric, vous avez raison au sujet de la non-linéarité (mais on peut peut-être faire quelque chose pour s'en accommoder et obtenir quand même un ILP).

4voto

Alan Points 3489

Plus j'y pense, plus j'ai l'impression qu'il s'agit de la programmation linéaire entière, qui est NP-complète dans le cas général. http://en.wikipedia.org/wiki/Linear_programming#Integer_unknowns

Mon raisonnement a commencé comme la réponse de TheMachineCharmer jusqu'à ce que j'atteigne ce point. Le problème est que l'approche consistant à examiner les lignes le long du plafond/plancher du point d'intersection ne fonctionne que si la section est alignée avec l'axe vertical ou horizontal à travers le point d'intersection. Il est plus probable que la section mince soit inclinée d'un certain angle par rapport à l'axe et que les voisins plafond/plancher ne coupent pas la section en coordonnées entières.

À ce stade, nous recherchons une combinaison entière des vecteurs unitaires naturels qui satisfasse les inégalités définissant notre section sélectionnée et qui minimise également la distance au point d'intersection. Pour moi, cela ressemble à un problème de programmation linéaire en nombres entiers.

Il existe des cas particuliers de programmation linéaire en nombres entiers qui sont plus faciles que NP-hard et ce problème pourrait facilement être l'un d'entre eux puisqu'il semble être plus contraint que le cas général de programmation linéaire. L'article de Wikipedia renvoie à quelques méthodes, mais leur application dépasse mon niveau de mathématique.

0 votes

Ce n'est pas tout à fait une ILP, cependant ; trouver le point le plus proche nécessite de minimiser x^2 + y^2, ce qui n'est pas une équation linéaire. Elle est cependant convexe, et entre donc dans la catégorie générale de l'optimisation convexe. Je n'ai pas regardé de près, mais je parie que les techniques de résolution des ILP par l'ajout de contraintes peuvent être généralisées pour résoudre l'optimisation convexe entière également.

0 votes

C'est vrai pour la non-linéarité du problème. J'avais pensé que la distance de Manhattan serait une approximation suffisante, mais après y avoir réfléchi un peu plus, ce n'est clairement pas le cas.

0 votes

Ça vous donnerait une limite supérieure pour la distance en x et y, en tout cas.

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