En algoritme for å løse et enkelt (?) Matrise problem

stemmer
7

For dette problemet hastigheten er ganske avgjørende. Jeg har tegnet et fint bilde å forklare problemet bedre. Algoritmen må beregne hvis kantene på et rektangel fortsette innenfor rammen av lerretet, vil kanten skjærer en firkant?

Vi vet:

  1. Størrelsen på lerretet
  2. Størrelsen av hvert rektangel
  3. Posisjonen av hvert rektangel

Jo raskere løsningen er bedre! Jeg er ganske fast på dette og ikke vet hvor du skal begynne.

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

Jubel

Publisert på 08/07/2010 klokken 12:23
kilden bruker
På andre språk...                            


6 svar

stemmer
2

Linjer som ikke er parallelle med hverandre kommer til å krysse på et tidspunkt. Beregn bakken av hver linje, og deretter bestemme hvilke linjer de ikke kommer til å krysse med.

Start med det, og så la oss se hvordan du kan optimalisere den. Jeg er ikke sikker på hvordan dataene er representert, og jeg kan ikke se bildet.

Ved hjelp av bakker er en enkel likestilling sjekk som sannsynligvis betyr at du kan dra nytte av å sortere dataene. Faktisk kan du sannsynligvis bare lage et sett med forskjellige bakker. Du må finne ut hvordan å representere dataene slik at de to bakkene i samme rektangel ikke telles som kryssende.

EDIT: Vent .. hvordan kan to rektangler som kanter går mot uendelig ikke overlappe? Rektangler er i utgangspunktet to linjer som er vinkelrett på hverandre. bør ikke det bety det alltid skjærer med en annen hvis disse linjene er utvidet til uendelig?

Svarte 08/07/2010 kl. 12:35
kilden bruker

stemmer
6

Bare opprette et sett av intervaller for hver av X- og Y-aksen. Da for hver ny rektangel, se om det er kryssende intervaller i X- eller Y-aksen. Se her for en måte å implementere intervall sett.

I din første eksempel vil intervallet stilt på den horisontale aksen være { [0-8], [0-8], [9-10] }, og på den vertikale:{ [0-3], [4-6], [0-4] }

Dette er bare en skisse, jeg abstrahert mange detaljer her (for eksempel vanligvis ville man spørre et intervall sett / tree "som intervaller lapper dette", i stedet for "krysser av dette", men ingenting ikke gjennomførbart).

Redigere

Vennligst se denne relatert MIT foredrag (det er litt lang, men worths absolutt det). Selv om du finner enklere løsninger (enn å gjennomføre en utvidet rød-svart tre), er det godt å vite ideene bak disse tingene.

Svarte 08/07/2010 kl. 12:36
kilden bruker

stemmer
1

så lenge du ikke nevner det språket du valgte å løse problemet, vil jeg bruke noen form for pseudo-kode

Ideen er at hvis alt er i orden, da en sortert samling av rektangelet kanter langs en akse bør være en sekvens av ikke-overlappende intervaller.

  1. nummer alle rektangler, tildele dem individuelle IDer
  2. opprette en tom binært tre samling (BTC). denne samlingen bør ha en fremgangsmåte for å sette inn et heltall node med informasjon BTC :: innsats (nøkkel, verdi)
  3. for alle rektangler, gjøre:

foreach rect in rects do
    btc.insert(rect.top, rect.id)
    btc.insert(rect.bottom, rect.id)
  1. nå iterere gjennom BTC (dette vil gi deg en sortert rekkefølge)

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 - 2,3,4 gjenta trinn for rect.left og rect.right koordinater

Svarte 08/07/2010 kl. 12:49
kilden bruker

stemmer
1

Jeg liker dette spørsmålet. Her er mitt forsøk på å komme på det:

Hvis mulig: Lag et polygon fra hvert rektangel. Behandle hver kant som en linje av den maksimale lengde som skal bli klippet. Bruk en klipping algoritme for å sjekke været eller ikke en linje skjærer med en annen. For eksempel denne: Linje Clipping

Men husk: Hvis du finner et kryss som er på toppunktet posisjon, dens gyldig.

Svarte 08/07/2010 kl. 13:01
kilden bruker

stemmer
1

Her er en idé. I stedet for å skape hvert rektangel med (x, y, width, height), instantiate dem med (x1, y1, x2, y2), eller i det minste har det tolke gitt bredde og høyde disse verdiene.

På den måten kan du sjekke hvilke rektangler har en lignende xeller yverdi og sørge for at den tilsvarende rektangelet har samme annenhåndsverdi.


Eksempel:

Rektanglene du har gitt har følgende verdier:

  • Firkantet 1: [0, 0, 8, 3]
  • Rute 3: [0, 4, 8, 6]
  • Firkantet 4: [9, 0, 10, 4]

Først sammenligner vi Square 1til Square 3(ingen kollisjon):

  • Sammenlign x-verdiene
    • [0, 8] til [0, 8] Dette er nøyaktig det samme, så det er ingen overgang.
  • Sammenlign y-verdier
    • [0, 4] til [3, 6] Ingen av disse tallene er like, slik at de ikke er en faktor

Deretter sammenligner vi Square 3til Square 4(kollisjon):

  • Sammenlign x-verdiene
    • [0, 8] til [9, 10] Ingen av disse tallene er like, slik at de ikke er en faktor
  • Sammenlign y-verdier
    • [4, 6] til [0, 4] Rektanglene har nummer 4 i felles, men 0! = 6, er det derfor en kollisjon

Ved vet vi vet at en kollisjon vil skje, slik at metoden vil ende, men lar evaluere Square 1og Square 4for litt ekstra klarhet.

  • Sammenlign x-verdiene
    • [0, 8] til [9, 10] Ingen av disse tallene er like, slik at de ikke er en faktor
  • Sammenlign y-verdier
    • [0, 3] til [0, 4] Rektanglene har nummer 0 til felles, men 3! = 4, og derfor er det en kollisjon

Gi meg beskjed hvis du trenger noen ekstra detaljer :)

Svarte 08/07/2010 kl. 13:08
kilden bruker

stemmer
0

Heh, tar de overlappende intervaller svarer til det ekstreme, du bare bestemme alle forskjellige intervaller langs x- og y-aksen. For hver skjærelinje, har en øvre grense søk langs aksen det vil kutte basert på intervallet sin startverdi. Hvis du ikke finner et intervall eller intervallet ikke krysser linjen, så er det en gyldig linje.

Den litt vanskelige delen er å innse at gyldige skjærelinjer ikke kommer til å krysse en rektangel er grenser langs en akse, slik at du kan kombinere overlappende intervaller i en enkelt intervall. Du ender opp med en enkel sortert array (som du fyller i O (n) tid) og en O (log n) søke for hver skjærelinjen.

Svarte 09/07/2010 kl. 06:53
kilden bruker

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