Bygglogg, Java projekt - En smart kublista

Permalänk
Medlem

Bygglogg, Java projekt - En smart kublista

Hej Sweclockare,

koden jag skriver är helt fri att använda sig av.

Projekt,
Mitt projekt är att skapa en nodlista som formar sig som en kub (Tänk er en rubikskub). Den ska kunna länkas vid 27 olika punkter, Vertikalt, horisontelt och diagonalt. Sedan tänkte jag försöka skapa en a-star search funktion som ska kunna snabbt och effektivt kunna söka sig fram genom kuben efter data.

Bakgrund,
Då jag har ungefär 1-1½ år av programmeringserfarenhet (Själv lärd) kommer jag använda mig av Java för att försöka lösa detta.

Övrigt
Detta är nog det svåraste projektet jag har tagit mig an, men ack så roligt det kan bli.

Jag kommer uppdatera denna tråd med kod som jag implementerar, problem och lösningar. Min tanke är att det kan vara roligt för nya, juniora och även seniora utvecklare att få följa en nybörjare i hur han tänker och gör.

Jag har fått tipset att använda mig av github också, vilket jag kommer lägga till lite senare.

Milstenar,
1. En algoritm, Rekursiv metod eller dylikt för att skapa noderna som en kub. Jag har kollat mycket på hilberts curve, men jag känner att jag har svårt att tolka fram bra fakta när jag har sökt runt. Metoden ska ta fram nästa punkt noden ska skapas.

2. Skapa en metod som kopplar samman noderna. Detta kommer nog bli extremt komplicerat, men definitivt lättare än milsten 1. Listan ska på ett smart och snyggt sätt kunna koppla samman alla sina 27 punkter, när det väl adderas en ny nod.

3. Skapa ett första utkast av en sökfunktion. Den ska ta sig från första till sista noden på ett snabbt och effektivt sätt.

4. Skapa add och remove metoder för noder inom själva kuben. Har inte riktigt bestämt hur jag ska göra här, då jag ej vill sortera hela kuben när något läggs till/tas bort. Till och börja med sätter jag nodens data till null

5. Det tar vi om jag lyckas komma så långt!

Min kod hittils

Hittills har jag bara skapat ett skal och lekt runt lite. Mitt första steg är att ta fram algoritmen för att skapa noderna i form av en kub.

public class CubeList <AnyType>{ private int uniqId = 0; private int sumDifferential = 0; private int sumTotal = 0; // Variables to keep track of the x,y and z position of the node. private int xAxis=1, yAxis=1, zAxis=1; //Store the first node and also the one being worked with. private Node <AnyType> firstNode; private Node <AnyType> currentNode; public void add (AnyType data) { System.out.println(getFirstNode()); try { if (getFirstNode() == null) { //Create node nr1. Node <AnyType> node = new Node<AnyType> (data, uniqId, xAxis, yAxis, zAxis); uniqId++; //Connect the first node with this one. setFirstNode(node); //Set the newly created node as the current one. setCurrentNode(node); } else { //Calculate the position of the node nextNodePosition(xAxis, yAxis, zAxis); //Create the new node Node <AnyType> node = new Node<AnyType> (data, uniqId, xAxis, yAxis, zAxis); uniqId++; //Connect the node with other nodes close by. connectNode(node); //Change the current node to the new created node. setCurrentNode(node); } } //Took the first best Exception so the catch statement doesn't complain. catch (NullPointerException e) { e.printStackTrace(); } } /** * This method calculate the position of the next node * */ private void nextNodePosition (int xAxis, int yAxis, int zAxis) { } /** * This method connect the newly created node, with other nearby nodes * */ private void connectNode (Node <AnyType> node) { } /** * Just a method to calculate the number of nodes which need to be added between each x³. * Example, between 2³ and 3³ there is 19 nodes. * * */ public void rekursivSumAll (int x) { if (x < 0) { return; } else if (x == 0) { sumDifferential += 1; sumTotal += sumDifferential; System.out.println("The value is: "+ sumDifferential); return; } else { sumDifferential += x*6; rekursivSumAll(x-1); } } /** * A private class to create a node for the cubeList. * The nodes store Anytype of data, position of x-,y-,z-axis and pointers to other nearby nodes * * * @author razkan * * @param <AnyType> * * */ private static class Node <AnyType> { //The node stored object private AnyType data; //X-Axis nodes private Node <AnyType> xAxisMiddle; private Node <AnyType> xAxisTop; private Node <AnyType> xAxisBottom; private Node <AnyType> xAxisRight; private Node <AnyType> xAxisLeft; private Node <AnyType> xAxisTopRightCorner; private Node <AnyType> xAxisTopLeftCorner; private Node <AnyType> xAxisBottomRightCorner; private Node <AnyType> xAxisBottomLeftCorner; //Y-Axis nodes private Node <AnyType> yAxisMiddle; private Node <AnyType> yAxisTop; private Node <AnyType> yAxisBottom; private Node <AnyType> yAxisRight; private Node <AnyType> yAxisLeft; private Node <AnyType> yAxisTopRightCorner; private Node <AnyType> yAxisTopLeftCorner; private Node <AnyType> yAxisBottomRightCorner; private Node <AnyType> yAxisBottomLeftCorner; //Z-Axis nodes private Node <AnyType> zAxisMiddle; private Node <AnyType> zAxisTop; private Node <AnyType> zAxisBottom; private Node <AnyType> zAxisRight; private Node <AnyType> zAxisLeft; private Node <AnyType> zAxisTopRightCorner; private Node <AnyType> zAxisTopLeftCorner; private Node <AnyType> zAxisBottomRightCorner; private Node <AnyType> zAxisBottomLeftCorner; private final int UNIQ_ID; private int xAxis, yAxis, zAxis; public Node (AnyType data, int uniq_id, int xAxis, int yAxis, int zAxis) { this.data = data; this.UNIQ_ID = uniq_id; this.xAxis = xAxis; this.yAxis = yAxis; this.zAxis = zAxis; } public AnyType getData() { return data; } public void setData(AnyType data) { this.data = data; } public int getUniqId() { return this.UNIQ_ID; } public int getxAxis() { return xAxis; } public void setxAxis(int xAxis) { this.xAxis = xAxis; } public int getyAxis() { return yAxis; } public void setyAxis(int yAxis) { this.yAxis = yAxis; } public int getzAxis() { return zAxis; } public void setzAxis(int zAxis) { this.zAxis = zAxis; } public Node<AnyType> getxAxisMiddle() { return xAxisMiddle; } public void setxAxisMiddle(Node<AnyType> xAxisMiddle) { this.xAxisMiddle = xAxisMiddle; } public Node<AnyType> getxAxisTop() { return xAxisTop; } public void setxAxisTop(Node<AnyType> xAxisTop) { this.xAxisTop = xAxisTop; } public Node<AnyType> getxAxisBottom() { return xAxisBottom; } public void setxAxisBottom(Node<AnyType> xAxisBottom) { this.xAxisBottom = xAxisBottom; } public Node<AnyType> getxAxisRight() { return xAxisRight; } public void setxAxisRight(Node<AnyType> xAxisRight) { this.xAxisRight = xAxisRight; } public Node<AnyType> getxAxisLeft() { return xAxisLeft; } public void setxAxisLeft(Node<AnyType> xAxisLeft) { this.xAxisLeft = xAxisLeft; } public Node<AnyType> getxAxisTopRightCorner() { return xAxisTopRightCorner; } public void setxAxisTopRightCorner(Node<AnyType> xAxisTopRightCorner) { this.xAxisTopRightCorner = xAxisTopRightCorner; } public Node<AnyType> getxAxisTopLeftCorner() { return xAxisTopLeftCorner; } public void setxAxisTopLeftCorner(Node<AnyType> xAxisTopLeftCorner) { this.xAxisTopLeftCorner = xAxisTopLeftCorner; } public Node<AnyType> getxAxisBottomRightCorner() { return xAxisBottomRightCorner; } public void setxAxisBottomRightCorner(Node<AnyType> xAxisBottomRightCorner) { this.xAxisBottomRightCorner = xAxisBottomRightCorner; } public Node<AnyType> getxAxisBottomLeftCorner() { return xAxisBottomLeftCorner; } public void setxAxisBottomLeftCorner(Node<AnyType> xAxisBottomLeftCorner) { this.xAxisBottomLeftCorner = xAxisBottomLeftCorner; } public Node<AnyType> getyAxisMiddle() { return yAxisMiddle; } public void setyAxisMiddle(Node<AnyType> yAxisMiddle) { this.yAxisMiddle = yAxisMiddle; } public Node<AnyType> getyAxisTop() { return yAxisTop; } public void setyAxisTop(Node<AnyType> yAxisTop) { this.yAxisTop = yAxisTop; } public Node<AnyType> getyAxisBottom() { return yAxisBottom; } public void setyAxisBottom(Node<AnyType> yAxisBottom) { this.yAxisBottom = yAxisBottom; } public Node<AnyType> getyAxisRight() { return yAxisRight; } public void setyAxisRight(Node<AnyType> yAxisRight) { this.yAxisRight = yAxisRight; } public Node<AnyType> getyAxisLeft() { return yAxisLeft; } public void setyAxisLeft(Node<AnyType> yAxisLeft) { this.yAxisLeft = yAxisLeft; } public Node<AnyType> getyAxisTopRightCorner() { return yAxisTopRightCorner; } public void setyAxisTopRightCorner(Node<AnyType> yAxisTopRightCorner) { this.yAxisTopRightCorner = yAxisTopRightCorner; } public Node<AnyType> getyAxisTopLeftCorner() { return yAxisTopLeftCorner; } public void setyAxisTopLeftCorner(Node<AnyType> yAxisTopLeftCorner) { this.yAxisTopLeftCorner = yAxisTopLeftCorner; } public Node<AnyType> getyAxisBottomRightCorner() { return yAxisBottomRightCorner; } public void setyAxisBottomRightCorner(Node<AnyType> yAxisBottomRightCorner) { this.yAxisBottomRightCorner = yAxisBottomRightCorner; } public Node<AnyType> getyAxisBottomLeftCorner() { return yAxisBottomLeftCorner; } public void setyAxisBottomLeftCorner(Node<AnyType> yAxisBottomLeftCorner) { this.yAxisBottomLeftCorner = yAxisBottomLeftCorner; } public Node<AnyType> getzAxisMiddle() { return zAxisMiddle; } public void setzAxisMiddle(Node<AnyType> zAxisMiddle) { this.zAxisMiddle = zAxisMiddle; } public Node<AnyType> getzAxisTop() { return zAxisTop; } public void setzAxisTop(Node<AnyType> zAxisTop) { this.zAxisTop = zAxisTop; } public Node<AnyType> getzAxisBottom() { return zAxisBottom; } public void setzAxisBottom(Node<AnyType> zAxisBottom) { this.zAxisBottom = zAxisBottom; } public Node<AnyType> getzAxisRight() { return zAxisRight; } public void setzAxisRight(Node<AnyType> zAxisRight) { this.zAxisRight = zAxisRight; } public Node<AnyType> getzAxisLeft() { return zAxisLeft; } public void setzAxisLeft(Node<AnyType> zAxisLeft) { this.zAxisLeft = zAxisLeft; } public Node<AnyType> getzAxisTopRightCorner() { return zAxisTopRightCorner; } public void setzAxisTopRightCorner(Node<AnyType> zAxisTopRightCorner) { this.zAxisTopRightCorner = zAxisTopRightCorner; } public Node<AnyType> getzAxisTopLeftCorner() { return zAxisTopLeftCorner; } public void setzAxisTopLeftCorner(Node<AnyType> zAxisTopLeftCorner) { this.zAxisTopLeftCorner = zAxisTopLeftCorner; } public Node<AnyType> getzAxisBottomRightCorner() { return zAxisBottomRightCorner; } public void setzAxisBottomRightCorner(Node<AnyType> zAxisBottomRightCorner) { this.zAxisBottomRightCorner = zAxisBottomRightCorner; } public Node<AnyType> getzAxisBottomLeftCorner() { return zAxisBottomLeftCorner; } public void setzAxisBottomLeftCorner(Node<AnyType> zAxisBottomLeftCorner) { this.zAxisBottomLeftCorner = zAxisBottomLeftCorner; } } private Node<AnyType> getFirstNode() { return firstNode; } private void setFirstNode(Node<AnyType> firstNode) { this.firstNode = firstNode; } private Node<AnyType> getCurrentNode() { return currentNode; } private void setCurrentNode(Node<AnyType> currentNode) { this.currentNode = currentNode; } }

Dold text
Permalänk
Medlem

Igår hade jag inte tid att hålla på med detta, på grund av strömavbrott.

Jag sökte fakta och verkar ha hittat en snubbe som har gjort hilbert 2d to 3d python version. Ska försöka skriva om den i java istället och se om den ger mig det resultat jag önskar. Får kolla på detta ikväll.

Säkert gjort något fel med koden jag snabbt skrev ihop.

public class TestMethods { int travel_bit; int modulus; int g; int rg; public int gray_encode_travel (int start, int end, int mask, int i) { travel_bit = start ^ end; modulus = mask + 1; g = i * ( travel_bit * 2); return ( ( g | ( g / modulus ) ) & mask ) ^ start ; } public int gray_decode_travel ( int start, int end, int mask, int g) { travel_bit = start ^ end; modulus = mask + 1; rg = ( rg ^ start ) * ( modulus / ( travel_bit * 2 ) ); return ( rg | ( rg / modulus ) ) & mask; } }

Dold text

När det står följande i python, return gray_decode( ( rg | ( rg / modulus ) ) & mask ) vart kommer "gray_decode()" i från? Metoden heter gray_decode_travel() så den kan inte vara rekursiv.

Permalänk
Hedersmedlem
Skrivet av Razki:

När det står följande i python, return gray_decode( ( rg | ( rg / modulus ) ) & mask ) vart kommer "gray_decode()" i från? Metoden heter gray_decode_travel() så den kan inte vara rekursiv.

Kodlistningen på översiktssidan är inte komplett, men om du tittar i den länkade `hilbert.py` så hittar du implementationen av funktionen `gray_decode` på rad 114:

# Gray encoder and decoder from http://en.wikipedia.org/wiki/Gray_code : # def gray_encode( bn ): assert bn >= 0 assert type( bn ) in [ int, long ] return bn ^ ( bn / 2 ) def gray_decode( n ): sh = 1 while True: div = n >> sh n ^= div if div <= 1: return n sh <<= 1

Ett annat alternativ hade varit ifall `gray_decode()` hade varit en del av standardbiblioteket i Python (men det är det inte, och standardbiblioteket hålls av en anledning litet nog för att man ska kunna känna igen dessa funktioner) eller om det hade importerats genom exempelvis `from en_extern_modul import *`, vilket får alla huvudnivåobjekt i `en_extern_modul` att importeras direkt in i rotnamnrymden i programmet (detta undviker man gärna om man inte har en speciell anledning, då namnrymder ofta är önskade att hålla separata).

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem
Skrivet av Razki:

Igår hade jag inte tid att hålla på med detta, på grund av strömavbrott.

Jag sökte fakta och verkar ha hittat en snubbe som har gjort hilbert 2d to 3d python version. Ska försöka skriva om den i java istället och se om den ger mig det resultat jag önskar. Får kolla på detta ikväll.

Säkert gjort något fel med koden jag snabbt skrev ihop.

public class TestMethods { int travel_bit; int modulus; int g; int rg; public int gray_encode_travel (int start, int end, int mask, int i) { travel_bit = start ^ end; modulus = mask + 1; g = i * ( travel_bit * 2); return ( ( g | ( g / modulus ) ) & mask ) ^ start ; } public int gray_decode_travel ( int start, int end, int mask, int g) { travel_bit = start ^ end; modulus = mask + 1; rg = ( rg ^ start ) * ( modulus / ( travel_bit * 2 ) ); return ( rg | ( rg / modulus ) ) & mask; } }

Dold text

När det står följande i python, return gray_decode( ( rg | ( rg / modulus ) ) & mask ) vart kommer "gray_decode()" i från? Metoden heter gray_decode_travel() så den kan inte vara rekursiv.

gray_decode() ser ut att definieras tre funktioner ovanför gray_decode_travel i hilbert.py:

def gray_decode( n ): sh = 1 while True: div = n >> sh n ^= div if div <= 1: return n sh <<= 1

Dold text
Visa signatur

i5 3570k @ 4.4GHz | MSI Z77A-G45 | Noctua NH-C12P | MSI GTX560Ti Twin Frozr | 8GB 1600MHz Corsair Vengeance LP| Corsair TX650W PSU | Benq V2410 LED

Permalänk
Medlem

Ser ut som ett roligt projekt! Vad ska du använda den datastrukturen till? Är det någon speciell data du vill lagra där det är intressant att traversera datastrukturen?

Mina funderingar:

1 och 2. Det kan vara så att du har en enorm kub med tusentals noder. Att då söka igenom nod efter nod om det "finns en plats ledig" är kanske en naiv och dålig lösning även om man optimerar bort de som redan har kontrollerats. Det går att optimera på andra sätt, exempelvis med någon slags hash eller liknande för varje nod som säger hur många kopplade noder som är lediga eller inte, då med bekostnad av minne istället för cpu. Jag är osäker på att Hilberts Curve kommer hjälpa dig att populera data om det är så att du har en befintlig stor kub med massa hål efter borttagning av värden. Ett sätt är att du använder A* för att ta reda på nästa nod/värde att skapas. Det är bara att du istället letar efter ett specifikt värde i en nod, letar efter den första tomma noden från origo.

3. Jag kan rekommendera att du lär dig samt implementerar A*-algoritmen i 2D innan du börjar med 3D. Att modifiera 2D-algoritmen till 3D är så pass enkel som att uppdatera två metoder (om du gör det rätt). Den ena metoden är node.getNeighbors() och den andra är vilken (eventuell) heuristics funktion som ska appliceras. Det är mycket klurigare att debugga en datastruktur i 3D än 2D. Inte omöjligt, men du sparar nog lite tid på att göra det klart i 2D först.

4. Det är nog helt rätt att inte bygga om hela strukturen när något tas bort eller läggs till. Eller har du planerat att lagra något sekvensiellt eller kategoriskt i din datastruktur? Om nodens data är null så kan du fortfarande traversera kuben förutsatt att du inte tar bort länkningarna som noden har/hade. Noden finns alltså kvar, men dess värde är borta.

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem

phz

Skrivet av phz:

Kodlistningen på översiktssidan är inte komplett, men om du tittar i den länkade `hilbert.py` så hittar du implementationen av funktionen `gray_decode` på rad 114:

# Gray encoder and decoder from http://en.wikipedia.org/wiki/Gray_code : # def gray_encode( bn ): assert bn >= 0 assert type( bn ) in [ int, long ] return bn ^ ( bn / 2 ) def gray_decode( n ): sh = 1 while True: div = n >> sh n ^= div if div <= 1: return n sh <<= 1

Ett annat alternativ hade varit ifall `gray_decode()` hade varit en del av standardbiblioteket i Python (men det är det inte, och standardbiblioteket hålls av en anledning litet nog för att man ska kunna känna igen dessa funktioner) eller om det hade importerats genom exempelvis `from en_extern_modul import *`, vilket får alla huvudnivåobjekt i `en_extern_modul` att importeras direkt in i rotnamnrymden i programmet (detta undviker man gärna om man inte har en speciell anledning, då namnrymder ofta är önskade att hålla separata).

Dold text

Min första misstanke var att det var en metod i standard biblioteket, eller att han skrev "ofärdig" kod. Eftersom jag har följt hans artikel steg för steg så hann jag inte komma till resten av hans python kod. Får kolla på dem när jag kommer hem och skriva om dem lite. Tycker om att spendera mina luncher med att fortsätta med mitt projekt. Annars är man så trött efter 8 timmars jobb.

Citruz

Skrivet av Citruz:

gray_decode() ser ut att definieras tre funktioner ovanför gray_decode_travel i hilbert.py:

def gray_decode( n ): sh = 1 while True: div = n >> sh n ^= div if div <= 1: return n sh <<= 1

Dold text
Dold text

Leedow

Tack för förtydligen. Ska kolla på dem bifogade python koderna i hans artikel!

Skrivet av Leedow:

Ser ut som ett roligt projekt! Vad ska du använda den datastrukturen till? Är det någon speciell data du vill lagra där det är intressant att traversera datastrukturen?

Mina funderingar:

1 och 2. Det kan vara så att du har en enorm kub med tusentals noder. Att då söka igenom nod efter nod om det "finns en plats ledig" är kanske en naiv och dålig lösning även om man optimerar bort de som redan har kontrollerats. Det går att optimera på andra sätt, exempelvis med någon slags hash eller liknande för varje nod som säger hur många kopplade noder som är lediga eller inte, då med bekostnad av minne istället för cpu. Jag är osäker på att Hilberts Curve kommer hjälpa dig att populera data om det är så att du har en befintlig stor kub med massa hål efter borttagning av värden. Ett sätt är att du använder A* för att ta reda på nästa nod/värde att skapas. Det är bara att du istället letar efter ett specifikt värde i en nod, letar efter den första tomma noden från origo.

3. Jag kan rekommendera att du lär dig samt implementerar A*-algoritmen i 2D innan du börjar med 3D. Att modifiera 2D-algoritmen till 3D är så pass enkel som att uppdatera två metoder (om du gör det rätt). Den ena metoden är node.getNeighbors() och den andra är vilken (eventuell) heuristics funktion som ska appliceras. Det är mycket klurigare att debugga en datastruktur i 3D än 2D. Inte omöjligt, men du sparar nog lite tid på att göra det klart i 2D först.

4. Det är nog helt rätt att inte bygga om hela strukturen när något tas bort eller läggs till. Eller har du planerat att lagra något sekvensiellt eller kategoriskt i din datastruktur? Om nodens data är null så kan du fortfarande traversera kuben förutsatt att du inte tar bort länkningarna som noden har/hade. Noden finns alltså kvar, men dess värde är borta.

Dold text

Anledningen till detta projekt är att skapa en effektiv datastruktur som har en effektiv sökalgoritm. Det går mycket snabbare för en kub att gå från start till end, då den bara behöver gå diagonalt 5-20 steg (5^3 eller 20^3). Däremot har du en länkad lista med 5^3/20^3 värden, behöver den gå igenom alla dessa för att komma till slutet.

Det jag hoppas är att jag kan skapa en ny och effektiv datastruktur som skulle kunna få hamna i ett bibliotek i något språk och användas av många personer. Sedan tycker jag det är roligt att bygga på min portfölj som jag i senare fall kan presentera för arbetsgivare.

1 & 2. Tanken är att du inte skapar en definierardlista, utan denna bygger på ut efter varje nytt objekt du adderar. Metoden jag önskar få fram är att du ska skicka in en count, och få ut vilken position nästan nod ska skapas. Exempelvis X = 10, Y = 5, Z = 3. Därefter ska noden kopplas samman direkt med närliggande noder, och närliggande noder kopplas samman med den nya.

3. Första sökalgoritmen blir simpel. Varje nod som skapas ska få ett unikt id, exempelvis 000000001, 000000002 etc. Sökfunktionen kommer få i uppgift att snabbast hitta X id. Exempelvis är jag på Nod 1 och ska ta mig till ID 300. Då kollar nod 1 vilken av närliggande noder som har det högsta ID värdet för att komma till 300.

4. Vid remove, tömmer jag nodens data och låter den ligga kvar. blir för trassligt med det unika IDet noden har. Får se om jag implementerar en Add in position metod. Eventuellt kanske jag skapar en replace funktion.

Permalänk
Medlem
Skrivet av Razki:

Anledningen till detta projekt är att skapa en effektiv datastruktur som har en effektiv sökalgoritm. Det går mycket snabbare för en kub att gå från start till end, då den bara behöver gå diagonalt 5-20 steg (5^3 eller 20^3). Däremot har du en länkad lista med 5^3/20^3 värden, behöver den gå igenom alla dessa för att komma till slutet.

Det jag hoppas är att jag kan skapa en ny och effektiv datastruktur som skulle kunna få hamna i ett bibliotek i något språk och användas av många personer. Sedan tycker jag det är roligt att bygga på min portfölj som jag i senare fall kan presentera för arbetsgivare.

Låt mig spela djävulens advokat.
Alla datastrukturer har lämpliga användningsområden. Vad skulle vara ett användningsområde för denna datastruktur? Varför ska man använda denna datastruktur istället för en annan? Är målet att hitta noden eller vägen till noden från en startnod baserat på vissa värden?
Att det går snabbt att komma någonstans vid traversering åt något håll är inte speciellt intressant när det är något man letar efter. Alla ställen måste det letas i ändå.

Jag rekommenderar att du bygger upp denna datastruktur i liten skala. Runt 100 objekt eller något sånt och jämföra sökning i den med en sökning i en vanlig array/ArrayList eller liknande och sen gå vidare till länkad lista kanske.

Kan du beskriva ungefär hur du tänker sökmetoden? Om det är en generic datastruktur så kan man stoppa in vad som helst. Hur är sökmetoden tänkt? Kan det tänkas finnas någon slags heuristics att använda ändå? Om ingen heuristics finns så kommer en sökning ta på tok för lång tid olyckligtvis.

Det är nog mer lämpligt med Dijkstra's algoritm än A*. Men principen blir densamma eftersom det troligtvis inte finns någon heuristics att använda då det är just slutnoden man försöker hitta, inte vägen. Grejen med pathfinding-algoritmer är ju att hitta kortaste vägen mellan start- och slutnod, inte att hitta slutnoden.

Här ser du hur det ser ut när man söker i alla grannoder från en startnod med Dijkstras algoritm. Detta är utan heuristics. A* presterar ungefär likadant utan en heuristic.

Med det sagt... att det går att traversera diagonalt blir meningslöst då alla noder ändå måste kontrolleras. Hur snabbt man hittar något är alltid i förhållande till vart man startar sökningen. Samma sak gäller för sökning i en vanlig array.

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem

Leedow

Skrivet av Leedow:

Låt mig spela djävulens advokat.
Alla datastrukturer har lämpliga användningsområden. Vad skulle vara ett användningsområde för denna datastruktur? Varför ska man använda denna datastruktur istället för en annan? Är målet att hitta noden eller vägen till noden från en startnod baserat på vissa värden?
Att det går snabbt att komma någonstans vid traversering åt något håll är inte speciellt intressant när det är något man letar efter. Alla ställen måste det letas i ändå.

Jag rekommenderar att du bygger upp denna datastruktur i liten skala. Runt 100 objekt eller något sånt och jämföra sökning i den med en sökning i en vanlig array/ArrayList eller liknande och sen gå vidare till länkad lista kanske.

Kan du beskriva ungefär hur du tänker sökmetoden? Om det är en generic datastruktur så kan man stoppa in vad som helst. Hur är sökmetoden tänkt? Kan det tänkas finnas någon slags heuristics att använda ändå? Om ingen heuristics finns så kommer en sökning ta på tok för lång tid olyckligtvis.

Det är nog mer lämpligt med Dijkstra's algoritm än A*. Men principen blir densamma eftersom det troligtvis inte finns någon heuristics att använda då det är just slutnoden man försöker hitta, inte vägen. Grejen med pathfinding-algoritmer är ju att hitta kortaste vägen mellan start- och slutnod, inte att hitta slutnoden.

Här ser du hur det ser ut när man söker i alla grannoder från en startnod med Dijkstras algoritm. Detta är utan heuristics. A* presterar ungefär likadant utan en heuristic.
http://upload.wikimedia.org/wikipedia/commons/2/23/Dijkstras_...

Med det sagt... att det går att traversera diagonalt blir meningslöst då alla noder ändå måste kontrolleras. Hur snabbt man hittar något är alltid i förhållande till vart man startar sökningen. Samma sak gäller för sökning i en vanlig array.

Dold text

Tack för tipsen!

Jag kanske får börja med att göra en generisk lista som hanterar slags data. Och när den gör steg 1 och 2. Så kanske jag får tänka på vart den skulle anpassas bäst och modifiera noderna. Min tanke är att ha prioriteret i noderna och att dem eventuellt väger olika tungt. Kommer krävas lite tankearbete!

Permalänk
Medlem

Efter mycket slit känner jag att mina kunskaper inom python och matematik inte är tillräckligt för att kunna konvertera följande hjälpavsnitt: http://www.tiac.net/~sw/2008/10/Hilbert/

Jag får göra så att jag tar Leedows tip med att börja med att skapa en 2D lista, och sedan lägga till metoder för att göra om den till 3D.

Någon som kan bra python och skulle kunna förklara bästa ekvalenta till Java kod.

Python,

def child_start_end( parent_start, parent_end, mask, i ): start_i = max( 0, ( i - 1 ) & ~1 ) # next lower even number, or 0 end_i = min( mask, ( i + 1 ) | 1 ) # next higher odd number, or mask child_start = gray_encode_travel( parent_start, parent_end, mask, start_i ) child_end = gray_encode_travel( parent_start, parent_end, mask, end_i ) return child_start, child_end

Dold text

Då java inte hanterar flera returer, vad jag har förstått så gjorde jag följande för att försöka matcha.

Java

public void child_start_end ( int parent_start, int parent_end, int mask, int i) { int start_i = Math.max( 0, ( i - 1 ) & ~1 ) ; int end_i = Math.min( mask, ( i + 1 ) | 1 ); child_start = gray_encode_travel ( parent_start, parent_end, mask, start_i); child_end = gray_encode_travel ( parent_start, parent_end, mask, end_i ); }

Dold text

Sedan lägga till två stycken getters

public int getChildStart () { return this.child_start; } public int getChildEnd () { return this.child_end; }

Dold text

Jag gör steg 1, 2 och 3 med en 2D lista innan jag konverterar den till en 3D och fortsätter med steg 4 och 5

Permalänk
Medlem

Nu är steg 1 avklarad för en 2D kvadrat. Notera, koden är RAW och jag har inte snyggat till den ännu.

KOD

/** * * @author razkan * * @param <AnyType> * */ public class SquareList <AnyType>{ private int uniqId = 1; // Variables to keep track of the x and y position of the node. private int x=0; private int y=0; private int n = 1; //Switch between x-axis = false and y-axis = true private boolean change = false; //Store the first node and also the one being worked with. private Node <AnyType> firstNode; private Node <AnyType> currentNode; public void add (AnyType data) { if (getX() == 0 && getY() == 0) { Node <AnyType> newNode = new Node<AnyType> (data, uniqId, getX(), getY()); uniqId++; //Set x = x + 1 setX(getX()+1); setFirstNode(newNode); setCurrentNode(newNode); } else { Node <AnyType> newNode = new Node<AnyType> (data, uniqId, getX(), getY()); uniqId++; setCurrentNode(newNode); nextPosition(getN(), getX(), getY()); } System.out.println(getCurrentNode()); } //X = n+1, Y = N // // // public void nextPosition (int n, int x, int y) { System.out.println("X Current: " + getX()); System.out.println("Y Current: " + getY()); System.out.println(); if (getN() <= 0 && getX() < 0 && getY() < 0) { return; } else { System.out.println("X Pre-Check: " + getX()); System.out.println("Y Pre-Check: " + getY()); System.out.println("N Pre-Check: " + getN()); System.out.println(); //Check if X and Y exceed their limit if (getX() > 0 && getY() <= getN()) { if (getX() >= getY() && change != true) { if (getX() == (getY()+1)) { change = true; } System.out.println("Y Before: " + getY()); setY(getY() + 1); System.out.println("Y After: " + getY()); System.out.println(); } else { System.out.println("X Before: " + getX()); setX(getX() - 1); System.out.println("X After: " + getX()); System.out.println(); } } //Set n+1 and go to next level. else { System.out.println("test"); setN(getN() + 1); setX(getN()); setY(0); change = false; } } } /** * A private class to create a node for the SquareList. * The nodes store Anytype of data, position of x- and y-axis with pointers to other nearby nodes * * * @author razkan * * @param <AnyType> * * Creates a Node with 8 connections in the following way. The node contains a uniq_id which is count and input data. * The data type is generic so it can contain any kind of variable. * * * 5 7 2 * |"""""""""""""""| * | | * | Unique ID | * 3| Data |4 * | X-Axis | * | Y-Axis | * |...............| * 1 8 6 * * */ private static class Node <AnyType> { //The node stored object private AnyType data; //A unique id which is previous node count +1; private final int UNIQ_ID; //xAxis and yXis of which the node can be placed. private int xAxis, yAxis; //Node connection one and two private Node <AnyType> bottomLeftCorner; private Node <AnyType> topRightCorner; //Node connection three and four private Node <AnyType> left; private Node <AnyType> right; //Node connection five and six private Node <AnyType> topLeftCorner; private Node <AnyType> bottomRightCorner; //Node connection seven and eight private Node <AnyType> top; private Node <AnyType> bottom; public Node (AnyType data, int uniq_id, int xAxis, int yAxis) { this.data = data; this.UNIQ_ID = uniq_id; this.xAxis = xAxis; this.yAxis = yAxis; } public AnyType getData() { return data; } public void setData(AnyType data) { this.data = data; } public int getUniqId() { return this.UNIQ_ID; } public int getxAxis() { return xAxis; } public void setxAxis(int xAxis) { this.xAxis = xAxis; } public int getyAxis() { return yAxis; } public void setyAxis(int yAxis) { this.yAxis = yAxis; } public Node<AnyType> getBottomLeftCorner() { return bottomLeftCorner; } public void setBottomLeftCorner(Node<AnyType> bottomLeftCorner) { this.bottomLeftCorner = bottomLeftCorner; } public Node<AnyType> getTopRightCorner() { return topRightCorner; } public void setTopRightCorner(Node<AnyType> topRightCorner) { this.topRightCorner = topRightCorner; } public Node<AnyType> getLeft() { return left; } public void setLeft(Node<AnyType> left) { this.left = left; } public Node<AnyType> getRight() { return right; } public void setRight(Node<AnyType> right) { this.right = right; } public Node<AnyType> getTopLeftCorner() { return topLeftCorner; } public void setTopLeftCorner(Node<AnyType> topLeftCorner) { this.topLeftCorner = topLeftCorner; } public Node<AnyType> getBottomRightCorner() { return bottomRightCorner; } public void setBottomRightCorner(Node<AnyType> bottomRightCorner) { this.bottomRightCorner = bottomRightCorner; } public Node<AnyType> getTop() { return top; } public void setTop(Node<AnyType> top) { this.top = top; } public Node<AnyType> getBottom() { return bottom; } public void setBottom(Node<AnyType> bottom) { this.bottom = bottom; } /* public String toString () { return "Data: " + getData() + "\n" + "ID: " + getUniqId() + "\n" + "Y-Axis: " + getyAxis() + "\n" + "X-Axis: " + getxAxis() + "\n" + "" + "\n" + "Node Connections status" + "\n" + "-----------------------" + "\n" + "" + "\n" + "1. Bottom Left: " + getBottomLeftCorner() + "\n" + "2. Top Right: " + getTopRightCorner() + "\n" + "3. Left: " + getLeft() + "\n" + "4. Right: " + getRight() + "\n" + "5. Top Left: " + getTopLeftCorner() + "\n" + "6. Bottom right: " + getBottomRightCorner() + "\n" + "7. Top: " + getTop() + "\n" + "8. Bottom: " + getBottom(); } */ } public int getUniqId() { return uniqId; } public void setUniqId(int uniqId) { this.uniqId = uniqId; } public int getN() { return n; } public void setN(int n) { this.n = n; } public Node<AnyType> getFirstNode() { return firstNode; } public void setFirstNode(Node<AnyType> firstNode) { this.firstNode = firstNode; } public Node<AnyType> getCurrentNode() { return currentNode; } public void setCurrentNode(Node<AnyType> currentNode) { this.currentNode = currentNode; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } }

Dold text

TESTCLASS

public class SquareListMain { public static void main (String[]args) { SquareList<Object> sl = new SquareList<Object>(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); sl.add(null); System.out.println(); } }

Dold text

Output från Testclass.

SquareList$Node@608a6351 X Current: 1 Y Current: 0 X Pre-Check: 1 Y Pre-Check: 0 N Pre-Check: 1 Y Before: 0 Y After: 1 SquareList$Node@1d7e8c5b X Current: 1 Y Current: 1 X Pre-Check: 1 Y Pre-Check: 1 N Pre-Check: 1 X Before: 1 X After: 0 SquareList$Node@5f30b97d X Current: 0 Y Current: 1 X Pre-Check: 0 Y Pre-Check: 1 N Pre-Check: 1 test SquareList$Node@77e1ee5d X Current: 2 Y Current: 0 X Pre-Check: 2 Y Pre-Check: 0 N Pre-Check: 2 Y Before: 0 Y After: 1 SquareList$Node@11e85928 X Current: 2 Y Current: 1 X Pre-Check: 2 Y Pre-Check: 1 N Pre-Check: 2 Y Before: 1 Y After: 2 SquareList$Node@2d355a47 X Current: 2 Y Current: 2 X Pre-Check: 2 Y Pre-Check: 2 N Pre-Check: 2 X Before: 2 X After: 1 SquareList$Node@9ba0281 X Current: 1 Y Current: 2 X Pre-Check: 1 Y Pre-Check: 2 N Pre-Check: 2 X Before: 1 X After: 0 SquareList$Node@12fa6824 X Current: 0 Y Current: 2 X Pre-Check: 0 Y Pre-Check: 2 N Pre-Check: 2 test SquareList$Node@75cb1d37 X Current: 3 Y Current: 0 X Pre-Check: 3 Y Pre-Check: 0 N Pre-Check: 3 Y Before: 0 Y After: 1 SquareList$Node@69eb424b X Current: 3 Y Current: 1 X Pre-Check: 3 Y Pre-Check: 1 N Pre-Check: 3 Y Before: 1 Y After: 2 SquareList$Node@544d8040 X Current: 3 Y Current: 2 X Pre-Check: 3 Y Pre-Check: 2 N Pre-Check: 3 Y Before: 2 Y After: 3 SquareList$Node@2c1f14fd X Current: 3 Y Current: 3 X Pre-Check: 3 Y Pre-Check: 3 N Pre-Check: 3 X Before: 3 X After: 2 SquareList$Node@2c9b04ac X Current: 2 Y Current: 3 X Pre-Check: 2 Y Pre-Check: 3 N Pre-Check: 3 X Before: 2 X After: 1 SquareList$Node@754fcf14 X Current: 1 Y Current: 3 X Pre-Check: 1 Y Pre-Check: 3 N Pre-Check: 3 X Before: 1 X After: 0 SquareList$Node@4aa46637 X Current: 0 Y Current: 3 X Pre-Check: 0 Y Pre-Check: 3 N Pre-Check: 3 test SquareList$Node@6f32cb29 X Current: 4 Y Current: 0 X Pre-Check: 4 Y Pre-Check: 0 N Pre-Check: 4 Y Before: 0 Y After: 1 SquareList$Node@6fb829c7 X Current: 4 Y Current: 1 X Pre-Check: 4 Y Pre-Check: 1 N Pre-Check: 4 Y Before: 1 Y After: 2 SquareList$Node@23bf011e X Current: 4 Y Current: 2 X Pre-Check: 4 Y Pre-Check: 2 N Pre-Check: 4 Y Before: 2 Y After: 3 SquareList$Node@50e26ae7 X Current: 4 Y Current: 3 X Pre-Check: 4 Y Pre-Check: 3 N Pre-Check: 4 Y Before: 3 Y After: 4 SquareList$Node@40d88d2d X Current: 4 Y Current: 4 X Pre-Check: 4 Y Pre-Check: 4 N Pre-Check: 4 X Before: 4 X After: 3 SquareList$Node@491ca69d X Current: 3 Y Current: 4 X Pre-Check: 3 Y Pre-Check: 4 N Pre-Check: 4 X Before: 3 X After: 2 SquareList$Node@77feb2ea X Current: 2 Y Current: 4 X Pre-Check: 2 Y Pre-Check: 4 N Pre-Check: 4 X Before: 2 X After: 1 SquareList$Node@72945e31 X Current: 1 Y Current: 4 X Pre-Check: 1 Y Pre-Check: 4 N Pre-Check: 4 X Before: 1 X After: 0 SquareList$Node@6ab41dbb X Current: 0 Y Current: 4 X Pre-Check: 0 Y Pre-Check: 4 N Pre-Check: 4 test SquareList$Node@570c16b7 X Current: 5 Y Current: 0 X Pre-Check: 5 Y Pre-Check: 0 N Pre-Check: 5 Y Before: 0 Y After: 1 SquareList$Node@5aa77506 X Current: 5 Y Current: 1 X Pre-Check: 5 Y Pre-Check: 1 N Pre-Check: 5 Y Before: 1 Y After: 2 SquareList$Node@27f40b69 X Current: 5 Y Current: 2 X Pre-Check: 5 Y Pre-Check: 2 N Pre-Check: 5 Y Before: 2 Y After: 3 SquareList$Node@7192efd X Current: 5 Y Current: 3 X Pre-Check: 5 Y Pre-Check: 3 N Pre-Check: 5 Y Before: 3 Y After: 4 SquareList$Node@65be7af X Current: 5 Y Current: 4 X Pre-Check: 5 Y Pre-Check: 4 N Pre-Check: 5 Y Before: 4 Y After: 5 SquareList$Node@7bc7956b

Dold text

Min algoritm baserades på följande uträkning. NOTERA, för mig är det lättare att visa bilder för att göra mig förstådd än att beskriva i ord, men tyvärr vet jag inte riktigt vad jag ska använda mig av för program för att kunna rita bilderna och sedan lägga till dem här.

Noderna skapas i en expanderande kvadrat.

N0 = 1 Nod
N1 = 4 Noder
N2 = 9 Noder
N3 = 16 Noder
Osv.

Skillnaden mellan Nx-1 och Nx = ( N * 2 ) + 1

Det jag noterade var när man ritar upp mellanskillnaden i en kladdbok är att i varje steg som ökar går det att skriva följande.
N1 (X, Y),
1,0
1,1 - Jag ger X denna punkt. (Diagonalen)
0,1

N2, (X,Y)
2,0
2,1
2,2 - Jag ger X denna punkt. (Diagonalen)
1,2
0,2

Då får jag att X = N + 1 och Y = N. ( N3; X = 4, Y = 3). Detta blev ganska lätt att skriva om till en if / else sats för att bygga nivå Nx.

Sen när jag vill hoppa till nästa nivå använde jag följande sats.

{ setN(getN() + 1); // Ökar N med 1 setX(getN()); //Sätter X = N för att börja på nästa nivå setY(0); //Sätter Y = 0 för att börja nästa nod på X = N och Y = 0 change = false; }

Dold text
Permalänk
Medlem

Nu kommer här en sen uppdatering. Jag slutar mitt uppdrag om 1 vecka och går på tjänsteledighet för studier. När jobbet slutar ska jag försöka uppdatera min bygglogg oftare eller senare. Beror helt på hur mycket tid som studierna tar.

Jag bifogar ett par bilder, då jag är en kråka på att förklara och jag känner att bilder illustrerar bättre.

Tyvärr har jag inte lärt mig hur jag bifogar bilder direkt in i ett inlägg så jag har länkat dem från min dropbox. Nu hoppas jag att jag har gjort rätt så att ni inte ser hela min dropbox.

EDIT, jag hittade hur jag kan bifoga bilder

Bild 1,

Dold text

Bild 2,

Dold text

Bild 3,

Dold text

Bild 1 illustrerar hur noderna ska byggas upp. Exempelvis Nod 7 ska kopplas samman med följande noder: 3 & 6, samt ge dem sin egen information. Ett exempel på detta kan se ut följande,

newNode.setBottomLeftCorner(newNode.getBottom().getLeft()); newNode.getBottomLeftCorner().setTopRightCorner(newNode);

Bild 2 illustrerar hur jag splittar kvadraten i två sektioner. Den ena kallar jag X och den andra Y. Det som är intressant är att Y aldrig behövs på X sidan. Dvs noderna som skapas där är alltid av ett högre värde.

Bild 3 illustrerar nedbryttningen av noderna. Notera att den svarta är nod nr 1 och den är fördefinerad, därför räknar jag inte in den i algoritmen, men än att jag lägger in den som startvärden i några variabler.

Det jag har gjort klart i dagsläget är steg 1 och halvt steg 2. Jag har skapat X sidan av kvadraten, och har Y sidan kvar.

Följande kod illustrerar hur noderna kopplas samman.

public void connectNode (Node <AnyType> newNode) { //Connecting on the X Coordinates //Node, ALL ON THE X SIDE if (newNode.getxAxis() >= newNode.getyAxis()) { // X => Y //Node 2, 3, 5, 6, 10, 11, 17, 18, 26, 27 if (newNode.getyAxis() <= (getPreviousDimension().getyAxis() + 1)) { //If newNode.getyAxis == 0 //Node 2, 5, 10, 17, 26 if (newNode.getyAxis() == 0) { newNode.setLeft(getPreviousDimension()); newNode.getLeft().setRight(newNode); //Sort out the second node out of the algorithm //Node 5, 10, 17, 26 if (newNode.getUniqId() != 2) { //Connect pointers 5 and 6 newNode.setTopLeftCorner(newNode.getLeft().getTop()); newNode.getTopLeftCorner().setBottomRightCorner(newNode); } } //If the newNode.getyAxis == 1; //Node 3, 6, 11, 18, 27 else { //Connect pointers 1 and 2 newNode.setBottomLeftCorner(getPreviousDimension()); newNode.getBottomLeftCorner().setTopRightCorner(newNode); //Connect pointers 7 and 8 newNode.setBottom(getPreviousDimension().getRight()); newNode.getBottom().setTop(newNode); //Node 6, 11, 18, 27 if (newNode.getUniqId() != 3) { //Connect pointers 3 and 4 newNode.setLeft(newNode.getBottomLeftCorner().getTop()); newNode.getLeft().setRight(newNode); } //Node 3 else { setPreviousDiagonal(newNode); } //Node 11, 18, 27 if (newNode.getUniqId() != 6 && newNode.getUniqId() != 3) { newNode.setTopLeftCorner(newNode.getLeft().getTop()); newNode.getTopLeftCorner().setBottomRightCorner(newNode); } } } //Where newNode.getx range between 1 and (max - 1), the nodes between diagonal and height y = 1 // //Node 12, 19, 20, 28, 29, 30 else if (newNode.getxAxis() > 1 && newNode.getxAxis() != newNode.getyAxis()) { //Connect Nodes on the y = 1 //Connect with the previous diagonal //If the node is y = (max-1) //Node 12, 20 and 30 if (newNode.getyAxis() == (getN()-1)) { //Connect pointers 3 and 4 newNode.setLeft(getPreviousDiagonal()); newNode.getLeft().setRight(newNode); newNode.setBottomLeftCorner(newNode.getLeft().getBottom()); newNode.getBottomLeftCorner().setTopRightCorner(newNode); newNode.setBottom(newNode.getBottomLeftCorner().getRight()); newNode.getBottom().setTop(newNode); //Node 12 if (newNode.getUniqId() == 12) { setPrevious(newNode); //System.out.println(newNode.getBottom()); } } else { //Node 19 and 28 if (newNode.getyAxis() == 2) { newNode.setLeft(getPrevious()); newNode.getLeft().setRight(newNode); setPrevious(newNode); setPreviousAlgorithmThree(newNode); newNode.setBottomLeftCorner(newNode.getLeft().getBottom()); newNode.getBottomLeftCorner().setTopRightCorner(newNode);; newNode.setBottom(newNode.getBottomLeftCorner().getRight()); newNode.getBottom().setTop(newNode); newNode.setTopLeftCorner(newNode.getLeft().getTop()); newNode.getTopLeftCorner().setBottomRightCorner(newNode); } //Node 29 + else { newNode.setBottom(getPreviousAlgorithmThree()); newNode.getBottom().setTop(newNode); setPreviousAlgorithmThree(newNode); newNode.setBottomLeftCorner(newNode.getBottom().getLeft()); newNode.getBottomLeftCorner().setTopRightCorner(newNode); newNode.setLeft(newNode.getBottomLeftCorner().getTop()); newNode.getLeft().setRight(newNode); newNode.setTopLeftCorner(newNode.getLeft().getTop()); newNode.getTopLeftCorner().setBottomRightCorner(newNode); } } } //Where newNode.getyAxis() == newNode.getxAxis(), The node created in the diagonal. //Node 7, 13, 21 else { newNode.setBottomLeftCorner(getPreviousDiagonal()); newNode.getBottomLeftCorner().setTopRightCorner(newNode); setPreviousDiagonal(newNode); newNode.setBottom(newNode.getBottomLeftCorner().getRight()); newNode.getBottom().setTop(newNode); } } } //Connecting on the Y side /* if () { } */

Dold text

Det jag har kvar innan steg 2 är klart och jag kan börja på min sökalgoritm är att fylla i följande.

//Connecting on the Y side /* if () { } */

Dold text

Jag jobbade stegvis med System.out.println(newNode); och testa med olika noder för att få fram att det stämde, System.out.println(newNode.getBottom());.

Exempel på output från olika noders positioner.
NOD 70.

Data: 70 ID: 70 N Dimension: 8 Y-Axis: 5 X-Axis: 8 Node Connections status ----------------------- 1. Bottom Left: true 2. Top Right: true 3. Left: true 4. Right: true 5. Top Left: true 6. Bottom right: true 7. Top: true 8. Bottom: true -----------------------

Dold text

NOD 7.

Data: 7 ID: 7 N Dimension: 2 Y-Axis: 2 X-Axis: 2 Node Connections status ----------------------- 1. Bottom Left: true 2. Top Right: true 3. Left: false 4. Right: true 5. Top Left: false 6. Bottom right: true 7. Top: false 8. Bottom: true -----------------------

Dold text

Nod 2.

Data: 2 ID: 2 N Dimension: 1 Y-Axis: 0 X-Axis: 1 Node Connections status ----------------------- 1. Bottom Left: false 2. Top Right: true 3. Left: true 4. Right: true 5. Top Left: false 6. Bottom right: false 7. Top: true 8. Bottom: false -----------------------

Dold text

Nedan bifogar jag fullständig källkod av mitt bygge. Jag vet, det är inte så snyggt ännu samt så har jag inte dokumenterat några metoder ännu. Men det kommer på slutet!

SquareList,

/** * * @author Razkan * * @param <AnyType> * */ public class SquareList <AnyType>{ private int uniqId = 1; // Variables to keep track of the x and y position of the node. private int x = 0; private int y = 0; private int n = 1; //Switch between x-axis = false and y-axis = true private boolean change = false; //Store the first node and also the one being worked with. private Node <AnyType> firstNode; //Node storages for connecting with other nodes. private Node <AnyType> next; private Node <AnyType> current; private Node <AnyType> previous; private Node <AnyType> previousAlgorithmThree; //Node to store the previous diagonal node, 1, 3, 7, 12, 21 etc private Node <AnyType> previousDiagonal; //if N = 4 then previousNDimension is the first node of N=3; private Node <AnyType> previousDimension; //Is used to store the x = n when y = 0 value then put in in previous nDimension when n += 1 private Node <AnyType> tempContainer; public void add (AnyType data) { if (getX() == 0 && getY() == 0) { Node <AnyType> newNode = new Node<AnyType> (data, uniqId, getX(), getY(), 0); uniqId++; //Set x = x + 1 setX(getX()+1); //Node links setFirstNode(newNode); setCurrent(newNode); setPreviousDimension(newNode); setPreviousDiagonal(newNode); } else { Node <AnyType> newNode = new Node<AnyType> (data, uniqId, getX(), getY(), getN()); //ID is increased by 1 uniqId++; setCurrent(newNode); //Connect newNode with everything beside it. connectNode(newNode); //Evaluate the next position of the X and Y nextPosition(newNode, getN(), getX(), getY()); } } //X = n+1, Y = N // // // public void nextPosition (Node <AnyType> newNode, int n, int x, int y) { //Check if the node is outside calculated borders if (getN() <= 0 || getX() < 0 || getY() < 0) { return; } else { //Check if X and Y exceed their limit if (getX() > 0 && getY() <= getN()) { if (getX() >= getY() && change != true) { //Store the node created on x == n, and y == 0, which will later be saved in the previousNdimension if (getY() == 0 && change == false) { setTempContainer(newNode); } //Switch from X growing to Y growing if (getX() == (getY()+1)) { change = true; } setY(getY() + 1); } else { setX(getX() - 1); } } //Set n+1 and go to next level. else { //Go to the next level n+1 setN(getN() + 1); //Start on the next level setX(getN()); //Reset the y position setY(0); //Reset the condition flag change = false; //Set the node into the n-1 position. Example x = 3, then previousNdimension x = 2 setPreviousDimension(getTempContainer()); } } } public void connectNode (Node <AnyType> newNode) { //Connecting on the X Coordinates //Node, ALL ON THE X SIDE if (newNode.getxAxis() >= newNode.getyAxis()) { // X => Y //Node 2, 3, 5, 6, 10, 11, 17, 18, 26, 27 if (newNode.getyAxis() <= (getPreviousDimension().getyAxis() + 1)) { //If newNode.getyAxis == 0 //Node 2, 5, 10, 17, 26 if (newNode.getyAxis() == 0) { newNode.setLeft(getPreviousDimension()); newNode.getLeft().setRight(newNode); //Sort out the second node out of the algorithm //Node 5, 10, 17, 26 if (newNode.getUniqId() != 2) { //Connect pointers 5 and 6 newNode.setTopLeftCorner(newNode.getLeft().getTop()); newNode.getTopLeftCorner().setBottomRightCorner(newNode); } } //If the newNode.getyAxis == 1; //Node 3, 6, 11, 18, 27 else { //Connect pointers 1 and 2 newNode.setBottomLeftCorner(getPreviousDimension()); newNode.getBottomLeftCorner().setTopRightCorner(newNode); //Connect pointers 7 and 8 newNode.setBottom(getPreviousDimension().getRight()); newNode.getBottom().setTop(newNode); //Node 6, 11, 18, 27 if (newNode.getUniqId() != 3) { //Connect pointers 3 and 4 newNode.setLeft(newNode.getBottomLeftCorner().getTop()); newNode.getLeft().setRight(newNode); } //Node 3 else { setPreviousDiagonal(newNode); } //Node 11, 18, 27 if (newNode.getUniqId() != 6 && newNode.getUniqId() != 3) { newNode.setTopLeftCorner(newNode.getLeft().getTop()); newNode.getTopLeftCorner().setBottomRightCorner(newNode); } } } //Where newNode.getx range between 1 and (max - 1), the nodes between diagonal and height y = 1 // //Node 12, 19, 20, 28, 29, 30 else if (newNode.getxAxis() > 1 && newNode.getxAxis() != newNode.getyAxis()) { //Connect Nodes on the y = 1 //Connect with the previous diagonal //If the node is y = (max-1) //Node 12, 20 and 30 if (newNode.getyAxis() == (getN()-1)) { //Connect pointers 3 and 4 newNode.setLeft(getPreviousDiagonal()); newNode.getLeft().setRight(newNode); newNode.setBottomLeftCorner(newNode.getLeft().getBottom()); newNode.getBottomLeftCorner().setTopRightCorner(newNode); newNode.setBottom(newNode.getBottomLeftCorner().getRight()); newNode.getBottom().setTop(newNode); //Node 12 if (newNode.getUniqId() == 12) { setPrevious(newNode); //System.out.println(newNode.getBottom()); } } else { //Node 19 and 28 if (newNode.getyAxis() == 2) { newNode.setLeft(getPrevious()); newNode.getLeft().setRight(newNode); setPrevious(newNode); setPreviousAlgorithmThree(newNode); newNode.setBottomLeftCorner(newNode.getLeft().getBottom()); newNode.getBottomLeftCorner().setTopRightCorner(newNode);; newNode.setBottom(newNode.getBottomLeftCorner().getRight()); newNode.getBottom().setTop(newNode); newNode.setTopLeftCorner(newNode.getLeft().getTop()); newNode.getTopLeftCorner().setBottomRightCorner(newNode); } //Node 29 + else { newNode.setBottom(getPreviousAlgorithmThree()); newNode.getBottom().setTop(newNode); setPreviousAlgorithmThree(newNode); newNode.setBottomLeftCorner(newNode.getBottom().getLeft()); newNode.getBottomLeftCorner().setTopRightCorner(newNode); newNode.setLeft(newNode.getBottomLeftCorner().getTop()); newNode.getLeft().setRight(newNode); newNode.setTopLeftCorner(newNode.getLeft().getTop()); newNode.getTopLeftCorner().setBottomRightCorner(newNode); } } } //Where newNode.getyAxis() == newNode.getxAxis(), The node created in the diagonal. //Node 7, 13, 21 else { newNode.setBottomLeftCorner(getPreviousDiagonal()); newNode.getBottomLeftCorner().setTopRightCorner(newNode); setPreviousDiagonal(newNode); newNode.setBottom(newNode.getBottomLeftCorner().getRight()); newNode.getBottom().setTop(newNode); } } } //Connecting on the Y side /* if () { } */ public void print () { System.out.println(getFirstNode().getRight()); } /** * A private class to create a node for the SquareList. * The nodes store Anytype of data, position of x- and y-axis with pointers to other nearby nodes * * * @author razkan * * @param <AnyType> * * Creates a Node with 8 connections in the following way. The node contains a uniq_id which is count and input data. * The data type is generic so it can contain any kind of variable. * * * 5 7 2 * |"""""""""""""""| * | | * | Unique ID | * 3| Data |4 * | X-Axis | * | Y-Axis | * |...............| * 1 8 6 * * */ private static class Node <AnyType> { //The node stored object private AnyType data; //A unique id which is previous node count +1; private final int UNIQ_ID; //xAxis and yXis of which the node can be placed. private int xAxis, yAxis; //What N dimension the node is on private int nDimension; //Node connection one and two private Node <AnyType> bottomLeftCorner; private Node <AnyType> topRightCorner; //Node connection three and four private Node <AnyType> left; private Node <AnyType> right; //Node connection five and six private Node <AnyType> topLeftCorner; private Node <AnyType> bottomRightCorner; //Node connection seven and eight private Node <AnyType> top; private Node <AnyType> bottom; public Node (AnyType data, int uniq_id, int xAxis, int yAxis, int nDim) { this.data = data; this.UNIQ_ID = uniq_id; this.nDimension = nDim; this.xAxis = xAxis; this.yAxis = yAxis; } public AnyType getData() { return data; } public void setData(AnyType data) { this.data = data; } public int getUniqId() { return this.UNIQ_ID; } public int getxAxis() { return xAxis; } public void setxAxis(int xAxis) { this.xAxis = xAxis; } public int getNDimension() { return nDimension; } public void setNDimension(int nDim) { this.nDimension = nDim; } public int getyAxis() { return yAxis; } public void setyAxis(int yAxis) { this.yAxis = yAxis; } public Node<AnyType> getBottomLeftCorner() { return bottomLeftCorner; } public void setBottomLeftCorner(Node<AnyType> bottomLeftCorner) { this.bottomLeftCorner = bottomLeftCorner; } public Node<AnyType> getTopRightCorner() { return topRightCorner; } public void setTopRightCorner(Node<AnyType> topRightCorner) { this.topRightCorner = topRightCorner; } public Node<AnyType> getLeft() { return left; } public void setLeft(Node<AnyType> left) { this.left = left; } public Node<AnyType> getRight() { return right; } public void setRight(Node<AnyType> right) { this.right = right; } public Node<AnyType> getTopLeftCorner() { return topLeftCorner; } public void setTopLeftCorner(Node<AnyType> topLeftCorner) { this.topLeftCorner = topLeftCorner; } public Node<AnyType> getBottomRightCorner() { return bottomRightCorner; } public void setBottomRightCorner(Node<AnyType> bottomRightCorner) { this.bottomRightCorner = bottomRightCorner; } public Node<AnyType> getTop() { return top; } public void setTop(Node<AnyType> top) { this.top = top; } public Node<AnyType> getBottom() { return bottom; } public void setBottom(Node<AnyType> bottom) { this.bottom = bottom; } /** * Check whether a node is connected to another node * * @param node to check if it is connected with another node * @return either true or false whether the node is connected to another node */ public boolean isConnected (Node <AnyType> node) { if (node != null) { return true; } else { return false; } } public String toString () { return "Data: " + getData() + "\n" + "ID: " + getUniqId() + "\n" + "N Dimension: " + getNDimension() + "\n" + "Y-Axis: " + getyAxis() + "\n" + "X-Axis: " + getxAxis() + "\n" + "" + "\n" + "Node Connections status" + "\n" + "-----------------------" + "\n" + "" + "\n" + "1. Bottom Left: " + isConnected(getBottomLeftCorner()) + "\n" + "2. Top Right: " + isConnected(getTopRightCorner()) + "\n" + "3. Left: " + isConnected(getLeft()) + "\n" + "4. Right: " + isConnected(getRight()) + "\n" + "5. Top Left: " + isConnected(getTopLeftCorner()) + "\n" + "6. Bottom right: " + isConnected(getBottomRightCorner()) + "\n" + "7. Top: " + isConnected(getTop()) + "\n" + "8. Bottom: " + isConnected(getBottom()) + "\n" + "" + "\n" + "-----------------------" + "\n" + "" + "\n"; } } private int getUniqId() { return uniqId; } private void setUniqId(int uniqId) { this.uniqId = uniqId; } private int getN() { return n; } private void setN(int n) { this.n = n; } private Node<AnyType> getFirstNode() { return firstNode; } private void setFirstNode(Node<AnyType> firstNode) { this.firstNode = firstNode; } private Node<AnyType> getCurrent() { return current; } private void setCurrent(Node<AnyType> current) { this.current = current; } private Node<AnyType> getNext() { return next; } private void setNext(Node<AnyType> next) { this.next = next; } private Node<AnyType> getPrevious() { return previous; } private void setPrevious(Node<AnyType> previous) { this.previous = previous; } private Node<AnyType> getPreviousDimension() { return previousDimension; } private void setPreviousDimension(Node<AnyType> previousDimension) { this.previousDimension = previousDimension; } private int getX() { return x; } private void setX(int x) { this.x = x; } private int getY() { return y; } private void setY(int y) { this.y = y; } public Node<AnyType> getPreviousDiagonal() { return previousDiagonal; } public void setPreviousDiagonal(Node<AnyType> previousDiagonal) { this.previousDiagonal = previousDiagonal; } public Node<AnyType> getTempContainer() { return tempContainer; } public void setTempContainer(Node<AnyType> tempContainer) { this.tempContainer = tempContainer; } public Node<AnyType> getPreviousAlgorithmThree() { return previousAlgorithmThree; } public void setPreviousAlgorithmThree(Node<AnyType> previousAlgorithmThree) { this.previousAlgorithmThree = previousAlgorithmThree; } }

Dold text

Main,

public class SquareListMain { public static void main (String[]args) { SquareList<Object> sl = new SquareList<Object>(); for (int i = 1; i < 100; i++) { sl.add(i); } sl.print(); } }

Dold text

Tycker någon detta är intressant jag håller på med, eller känns det mest som att jag tar upp plats i forumet?

Tack!

Permalänk
Medlem

Nu är Y sidan av datastrukturen klar.

Följande kod illustrerar Y sidan.

//Connecting on the Y side if (newNode.getxAxis() < newNode.getyAxis()) { //Algoritm 1: Nodes: 4, 9, 16, 25 etc if (newNode.getyAxis() == newNode.getNDimension() && newNode.getxAxis() == 0) { if (newNode.getUniqId() == 4) { setPreviousYDiagonal(newNode); } setTempYContainer(newNode); newNode.setBottom(getPreviousYDimension()); newNode.getBottom().setTop(newNode); newNode.setBottomRightCorner(newNode.getBottom().getRight()); //wait for algoritm 2 and 3 to be done (Node 8, 15, 24 etc) newNode.getBottomRightCorner().setTopLeftCorner(newNode); //wait for algoritm 2 and 3 to be done (Node 8, 15, 24 etc) newNode.setRight(newNode.getBottom().getTopRightCorner()); newNode.getRight().setLeft(newNode); } //Algorithm 3, Node: 8, 14, 22 etc else if (newNode.getxAxis() == (newNode.getNDimension() - 1) && newNode.getyAxis() == newNode.getNDimension()) { //I have added node nr 4 to a get previous y diagonal. //Start with algorithm 3 and connect node 4 and 8 etc. newNode.setBottomLeftCorner(getPreviousYDiagonal()); newNode.getBottomLeftCorner().setTopRightCorner(newNode); setPreviousYDiagonal(newNode); setPreviousAlgorithmTwoY(newNode); newNode.setBottom(newNode.getBottomLeftCorner().getRight()); newNode.getBottom().setTop(newNode); newNode.setRight(newNode.getBottom().getTopRightCorner()); newNode.getRight().setLeft(newNode); newNode.setBottomRightCorner(newNode.getBottom().getRight()); newNode.getBottomRightCorner().setTopLeftCorner(newNode); } //Algorithm 2, Node: 15, 23, 24 etc else { newNode.setRight(getPreviousAlgorithmTwoY()); newNode.getRight().setLeft(newNode); setPreviousAlgorithmTwoY(newNode); newNode.setBottomRightCorner(newNode.getRight().getBottom()); newNode.getBottomRightCorner().setTopLeftCorner(newNode); newNode.setBottom(newNode.getBottomRightCorner().getLeft()); newNode.getBottom().setTop(newNode); newNode.setBottomLeftCorner(newNode.getBottom().getLeft()); newNode.getBottomLeftCorner().setTopRightCorner(newNode); } } }

Dold text

Nu ska jag skapa några olika sökalgoritmer. För närvarande är datastrukturen generisk och han hantera all slags data. Jag får se på vilket sätt datat ska skapas.

Den första sökalgoritmen blir en simpel där jag skriver in ett värde, och att den då ska hitta snabbast vägen dit.

Senare ska jag lägga in lite data i noderna, exempelvis namn och förmodligen blir det en algoritm som går igenom varje nod.