コード例 #1
0
ファイル: GNNNet.cs プロジェクト: riha112/GNNNeat
    // -- END OF: Feed forward --

    // HOW BREEDING WORKS:
    // 1. Two parents
    // 2. If both have connection then random
    // 3. If one have then take from strongest
    public GNNNet Breed(GNNNet parthner)
    {
        GNNNet child = new GNNNet();

        int[] range   = UTYL.InnovRange(connections, parthner.connections);
        bool  isAsFit = fitnessScore == parthner.fitnessScore;

        GNNNet[] parents = new GNNNet[] { this, parthner };
        Connect?[,] table = new Connect?[2, range[1] - range[0]];

        for (int i = 0; i < 2; i++)
        {
            for (int c = 0; c < parents[i].connections.Count; c++)
            {
                table[i, parents[i].connections[c].innov - range[0]] = parents[i].connections[c];
            }
        }

        for (int c = 0; c < range[1] - range[0]; c++)
        {
            // If both cells are empty, or parhner is less fit then skip connection
            if ((table[0, c] == null && table[1, c] == null) || (!isAsFit && table[0, c] == null))
            {
                continue;
            }

            // If both have same fitness adds parthners connection
            if (table[0, c] == null)
            {
                child.connections.Add(table[1, c].Value);
            }
            // Adds my connection if prev is empty
            else if (table[1, c] == null)
            {
                child.connections.Add(table[0, c].Value);
            }
            // If both have connections select random
            else
            {
                child.connections.Add(table[Random.Range(0, 2), c].Value);
            }
        }

        child.BuildNodes();
        return(child);
    }
コード例 #2
0
ファイル: Agent.cs プロジェクト: riha112/GNNNeat
    private double[,] GetSensorData()
    {
        double[,] output = new double[2, DIR_COUNT];

        RaycastHit2D hit;

        for (int i = 0; i < DIR_COUNT; i++)
        {
            Vector3 to = transform.TransformDirection(sensorDir[i]);
            hit = Physics2D.Raycast(transform.position, to);

            output[0, i] = -1;
            output[1, i] = 1;

            if (hit.collider != null)
            {
                string hitTag = hit.collider.tag;
                output[1, i] = hit.distance / 430.0;

                if (hitTag == "Food")
                {
                    output[0, i] = 1;
                    if (hit.distance < 2)
                    {
                        UTYL.RemoveFood(hit.collider.gameObject);
                        Destroy(hit.collider.gameObject);
                        score++;
                        health += 10;
                        if (health > 100)
                        {
                            health = 100;
                        }
                    }
                }
                else if (hitTag == "AI")
                {
                    output[0, i] = 0.5;
                }
                else if (hitTag == "Box")
                {
                    output[0, i] = -0.5;
                }
            }
        }
        return(output);
    }
コード例 #3
0
    void InitGeneration()
    {
        // Step 0: Cleanup after prev GEN
        CleanUp();

        // STEP 0.25 Backup
        SaveLoadManager.Save(GEN, unisignedNet);

        // STEP 0.5: Init  food
        UTYL.InitBox();

        // Step 1: Sort unisigned networks into spiecies
        // Step 2: Build simulations
        SpieciefyNetworks();

        // Step 3: Run simmulations
        StartCoroutine("UpdateSimulation");
    }
コード例 #4
0
    private void SpieciefyNetworks()
    {
        activeSimulations = new List <GNNSimulation>();
        spiecies          = new List <GNNSpiecies>();

        foreach (GNNNet net in unisignedNet)
        {
            activeSimulations.Add(new GNNSimulation()
            {
                agent   = UTYL.InitAgent(),
                network = net
            });

            activeSimulations.Last().SetName();

            bool isNewSpiecies = true;
            for (int i = 0; i < spiecies.Count; i++)
            {
                double dist = UTYL.GetDistance(spiecies[i].head, net);
                //Debug.Log("Dist:" + dist);
                if (dist <= 3)
                {
                    spiecies[i].family.Add(net);
                    isNewSpiecies = false;
                    break;
                }
            }

            if (isNewSpiecies)
            {
                spiecies.Add(new GNNSpiecies(net));
            }
        }

        for (int i = spiecies.Count - 1; i >= 0; i--)
        {
            if (spiecies[i].family.Count == 0)
            {
                spiecies.RemoveAt(i);
            }
        }
    }
コード例 #5
0
    private void Start()
    {
        UTYL.agentPrefab = Resources.Load("prefabs/AI") as GameObject;
        UTYL.foodPrefab  = Resources.Load("prefabs/Food") as GameObject;
        UTYL.boxPrefab   = Resources.Load("prefabs/Box") as GameObject;

        unisignedNet = new List <GNNNet>();
        SaveObject so = SaveLoadManager.Load();

        if (so == null) // No save file new sim
        {
            DB.SendData("clean_up", new Dictionary <string, string>());

            for (int i = 0; i < CONFIG.POPULATION; i++)
            {
                GNNNet net = new GNNNet();

                for (ushort o = 0; o < 4; o++)
                {
                    net.MutateLink();
                }

                net.connections = net.connections.OrderBy(x => x.innov).ToList();
                unisignedNet.Add(net);
            }
        }
        else
        {
            unisignedNet.AddRange(so.networks);
            GEN = so.GEN;
            InnovController.innovations = new List <Innovation>(so.innovations);
            unisignedNet.RemoveAt(0);
            InnovController.innov = so.innovID;
        }

        UTYL.InitFood();
        InitGeneration();
    }
コード例 #6
0
ファイル: UTYL.cs プロジェクト: riha112/GNNNeat
    // δ = E/N + D/N + W/M | + U/N, where U - is count of difrence in disabled
    public static double GetDistance(GNNNet a, GNNNet b)
    {
        if (a.connections.Count == 0 && b.connections.Count == 0)
        {
            return(0);
        }

        double W;
        int    M, D, E, N, U;

        M = 1;
        W = D = E = U = 0;

        N = a.connections.Count;
        if (N < b.connections.Count)
        {
            N = b.connections.Count;
        }

        if (N < 10)
        {
            N = 3;
        }

        GNNNet[] nets  = new GNNNet[] { a, b };
        int[]    range = UTYL.InnovRange(a.connections, b.connections);
        Connect?[,] table = new Connect?[2, range[1] - range[0]];

        for (int i = 0; i < 2; i++)
        {
            for (int c = 0; c < nets[i].connections.Count; c++)
            {
                table[i, nets[i].connections[c].innov - range[0]] = nets[i].connections[c];
            }
        }


        bool isDisjoint = true;

        for (int c = range[1] - range[0] - 1; c >= 0; c--)
        {
            // End of
            if (table[0, c] != null || table[1, c] != null)
            {
                isDisjoint = false;
            }

            if (isDisjoint)
            {
                D++;
                continue;
            }

            if (table[0, c] == null && table[1, c] != null || table[0, c] != null && table[1, c] == null)
            {
                E++;
                continue;
            }

            if (table[0, c] != null && table[1, c] != null)
            {
                if (table[0, c].Value.isDisabled != table[1, c].Value.isDisabled)
                {
                    U++;
                }

                M++;
                W += System.Math.Abs(table[0, c].Value.weight - table[1, c].Value.weight);
            }
        }
        return((double)E / (double)N +
               (double)D / (double)N +
               (double)U / (double)N +
               W / M);
    }
コード例 #7
0
 private void Update()
 {
     UTYL.KeepFood();
 }