Een algoritme om een ​​eenvoudige (?) Matrix oplossen

stemmen
7

Voor dit probleem snelheid is vrij cruciaal. Ik heb een leuk plaatje gevestigd op het probleem beter uit te leggen. Het algoritme dient te berekenen of randen van een rechthoek blijft binnen de grenzen van het doek, wordt de rand kruisen elkaar rechthoek?

Wij weten:

  1. De afmetingen van het doek
  2. De grootte van elke rechthoek
  3. De positie van elke rechthoek

Hoe sneller de oplossing is, hoe beter! Ik ben er vrij vast te zitten op dit ene en niet echt weet waar te beginnen.

alt-tekst http://www.freeimagehosting.net/uploads/8a457f2925.gif

Proost

De vraag is gesteld op 08/07/2010 om 13:23
bron van user
In andere talen...                            


6 antwoorden

stemmen
2

Lijnen die niet parallel aan elkaar gaan kruisen op een bepaald punt. Bereken de helling van elke lijn en vervolgens bepalen welke lijnen ze niet zullen kruisen.

Begin met dat, en dan laten we eens kijken hoe deze te optimaliseren. Ik ben niet zeker hoe uw gegevens vertegenwoordigd is en ik kan niet zien uw imago.

Met behulp van hellingen is een eenvoudige gelijkheid check wat waarschijnlijk betekent dat u kunt profiteren van het sorteren van de gegevens. In feite kun je waarschijnlijk gewoon een set van verschillende hellingen. Je moet om erachter te komen hoe de gegevens zodanig dat de twee hellingen van dezelfde rechthoek niet als kruisende geteld vertegenwoordigen.

EDIT: Wacht .. hoe kan twee rechthoeken waarvan de randen gaan tot in het oneindige niet snijden? Rechthoeken zijn twee lijnen die loodrecht op elkaar zijn. zou dat niet moeten zeggen dat het altijd kruist met een ander als die lijnen worden uitgebreid tot in het oneindige?

antwoordde op 08/07/2010 om 13:35
bron van user

stemmen
6

Maakt gewoon de set tijden voor elk van de X- en de Y-as. Vervolgens voor elke nieuwe rechthoek, of er kruisende afstanden in de X- of de Y-as. Zie hier voor een manier om de uitvoering van het interval sets.

In eerste voorbeeld, zou de op de horizontale as interval { [0-8], [0-8], [9-10] }en de verticale:{ [0-3], [4-6], [0-4] }

Dit is slechts een schets, ik geabstraheerd veel details hier (zoals gewoonlijk zou men een interval set / tree "die intervallen overlappen this one" te vragen, in plaats van "kruisen this one", maar niets niet uitvoerbaar).

Bewerk

Let altijd op deze verbonden MIT lezing (het is een beetje lang, maar absoluut was amazing). Zelfs als u eenvoudiger oplossingen te vinden (dan het implementeren van een augmented rood-zwarte boom), het is goed om de ideeën achter deze dingen te leren kennen.

antwoordde op 08/07/2010 om 13:36
bron van user

stemmen
1

zolang je niet de taal die u koos om het probleem op te lossen heeft genoemd, zal ik een soort van pseudo-code te gebruiken

het idee is dat als alles in orde is, dan een gesorteerde verzameling rechthoek randen langs één as zou een reeks niet-overlappende intervallen.

  1. nummer al uw rechthoeken, het toewijzen van hen individuele ids
  2. Maak een lege binaire boom collectie (BTC). collectie zou een methode om een ​​integer knooppunt info inzetstuk BTC :: insert (key, value)
  3. voor alle rechthoeken, doen:

foreach rect in rects do
    btc.insert(rect.top, rect.id)
    btc.insert(rect.bottom, rect.id)
  1. nu doorlopen van de BTC (dit zal u een gesorteerde bestelling)

btc_item = btc.first()
do
    id = btc_item.id
    btc_item = btc.next()
    if(id != btc_item.id)
    then report_invalid_placement(id, btc_item.id)
    btc_item = btc.next()
while btc_item is valid

5,7,8 - herhaal stap 2,3,4 voor rect.left en rect.right coördinaten

antwoordde op 08/07/2010 om 13:49
bron van user

stemmen
1

Ik hou van deze vraag. Hier is mijn poging op te krijgen:

Indien mogelijk: Maak een veelhoek van elke rechthoek. Behandel elke rand een lijn met de grootste lengte die moet worden geknipt. Gebruik een clipping algoritme om weer te controleren of niet een lijn kruist met een ander. Bijvoorbeeld deze: Line Clipping

Maar houd in gedachten: Als u een kruispunt dat bij de top positie, het is een geldige vinden.

antwoordde op 08/07/2010 om 14:01
bron van user

stemmen
1

Hier is een idee. In plaats van elke rechthoek met (x, y, width, height)Instantieer hen (x1, y1, x2, y2), of tenminste zij deze waarden de breedte en hoogte interpreteren.

Op die manier kunt u controleren welke rechthoeken een soortgelijke hebben xof ywaarde en zorg ervoor dat de overeenkomstige rechthoek heeft dezelfde secundaire waarde.


Voorbeeld:

De rechthoeken u gegeven heb de volgende waarden:

  • Vierkant 1: [0, 0, 8, 3]
  • Vierkant 3: [0, 4, 8, 6]
  • Square 4: [9, 0, 10, 4]

Ten eerste, we vergelijken Square 1met Square 3(botsing):

  • Vergelijk de x-waarden
    • [0, 8] op [0, 8] Dit zijn precies hetzelfde, dus er is geen crossover.
  • Vergelijk de y-waarden
    • [0, 4] om [3, 6] Geen van deze nummers op elkaar lijken, zodat ze niet een factor

Vervolgens hebben we vergelijken Square 3met Square 4(botsing):

  • Vergelijk de x-waarden
    • [0, 8] [9, 10] Geen van deze nummers op elkaar lijken, zodat ze niet een factor
  • Vergelijk de y-waarden
    • [4, 6] tot [0, 4] De rechthoeken het nummer 4 gemeen, maar 0! = 6, is er dus een botsing

Door kennis weten we dat een botsing zal optreden, zodat de methode zal eindigen, maar laat te evalueren Square 1en Square 4voor wat extra duidelijkheid.

  • Vergelijk de x-waarden
    • [0, 8] [9, 10] Geen van deze nummers op elkaar lijken, zodat ze niet een factor
  • Vergelijk de y-waarden
    • [0, 3] tot [0, 4] De rechthoeken het nummer 0 gemeen, maar 3! = 4, dan is er een botsing

Laat het me weten als u extra informatie nodig hebt :)

antwoordde op 08/07/2010 om 14:08
bron van user

stemmen
0

Heh, waarbij de overlappende intervallen antwoord op de extreme, je gewoon allemaal verschillend intervallen langs de x- en y-as te bepalen. Voor iedere snijlijn, doe een bovengrens zoeken langs de as zal gesneden op basis van de tussentijd de startwaarde. Als u niet beschikt over een interval te vinden of het interval niet snijdt de lijn, dan is het een geldige lijn.

De licht lastige is te realiseren dat geldige snijlijnen geen grenzen rechthoek zal snijden langs een as, zodat u overlappende intervallen combineren tot één interval. Je eindigt met een eenvoudige gesorteerde array (die u in O (n) tijd te vullen) en een O (log n) te zoeken voor elke snijlijn.

antwoordde op 09/07/2010 om 07:53
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more