带有三角形的算法任务

An algorithmic task with triangles

我有一个算法任务有问题。里面有内容:“你在一个平面上有十个点,其中none三个共线,每对不同的点用线段连接,线段是绿色或蓝色。计算有多少个三角形只有边一种颜色。”我尝试了一个 n 元树的解决方案,但我在结果列表中得到了带有整数循环排列的重复三角形。

Patryk,这个问题可以用n-树解决。但是,为了避免循环排列,您需要跳过对称线段。如果从 0 -> 1 创建线段,则不需要从 1 -> 0 创建线段。下面是一个完整的代码,它通过递归深度优先搜索解决了 n 树的问题。请原谅 类 和方法的波兰名称。不过界面是英文的。如果您分析代码,您一定会明白这一点。

from random import choice
import copy

class Punkt:
    def __init__(self, numer):
        self.__numer = numer
        self.__odcinki = {}

    def dodaj_odcinek_wychodzący(self, punkt_docelowy, kolor):
        self.__odcinki[punkt_docelowy] = Odcinek(self.__numer, punkt_docelowy, kolor)

    def wez_odcinek_do_punktu_docelowego(self, punkt_docelowy):
        return (punkt_docelowy, self.__odcinki[punkt_docelowy].wez_kolor())

    def liczba_odcinkow(self):
        return len(self.__odcinki)

    def wez_kolor_punktu_docelowego(self, punkt_docelowy):
        return self.__odcinki[punkt_docelowy].wez_kolor()

    def lista_punktow_docelowych(self):
        return self.__odcinki.keys()


class Odcinek:
    def __init__(self, punkt_zrodlowy, punkt_docelowy, kolor):
        self.__punkt_zrodlowy = punkt_zrodlowy
        self.__punkt_docelowy = punkt_docelowy
        self.__kolor = kolor

    def wez_kolor(self):
        return self.__kolor


class Structure:
    def __init__(self, liczba_punktow=10):
        self.__punkty = [Punkt(i)
                         for i in range(liczba_punktow)]
        for i in range(liczba_punktow):
            for j in range(i + 1, liczba_punktow):
                self.__punkty[i].dodaj_odcinek_wychodzący(j, choice(["green", "blue"]))
        # for j in range(liczba_punktow):
        #     for i in range (j + 1, liczba_punktow):
        #         self.__punkty[j].dodaj_odcinek_wychodzący(*(self.__punkty[j].wez_odcinek_do_punktu_docelowego(i)))

    def wez_punkt(self, numer):

        return self.__punkty[numer]

    def wez_liczbe_punktow(self):

        return len(self.__punkty)


class Search:

    def __init__(self, struktura):

        self.__s = struktura

    def wez_liczbe_punktow(self):

        return self.__s.wez_liczbe_punktow()

    def wez_punkt(self, numer):

        return self.__s.wez_punkt(numer)

    def szukaj(self, kolor="green"):

        self.__szukany_kolor = kolor

        lista_trojkatow = []

        liczba_trojkatow = 0

        wszystkie_trojkaty = []

        for i in range(self.wez_liczbe_punktow()):

            lista_odwiedzonych_punktow = [i]

            lista_trojkatow = self.szukaj_z_punktu(i,lista_odwiedzonych_punktow,lista_trojkatow)

        return len(lista_trojkatow), lista_trojkatow

    def wez_szukany_kolor(self):

        return self.__szukany_kolor

    def szukaj_z_punktu(self, numer, trojkat, lista_trojkatow):

        if len(trojkat) == 3: # jeżeli zebraliśmy już trzy punkty to brakuje tylko zamykającego, czwartego

            if self.wez_punkt(trojkat[0]).wez_kolor_punktu_docelowego(
                trojkat[-1]) == self.wez_szukany_kolor(): # sprawdź czy do punktu zamykającego prowadzi odcinek o szukanym kolorze

                trojkat.append(trojkat[0]) # dodaj punkt zamykajacy do trójkąta

                lista_trojkatow.append(trojkat) # dodaj trojkąt do listy trójkątów

                # return lista_trojkatow # zwróć liste trójkątów obliczonych dotychczas
        else:

            potomkowie = []
            for punkt_docelowy in self.wez_punkt(numer).lista_punktow_docelowych():
                if self.wez_punkt(numer).wez_kolor_punktu_docelowego(punkt_docelowy) == self.wez_szukany_kolor():
                    potomkowie.append(punkt_docelowy)

            for potomek in potomkowie:
                trojkat_kopia = copy.copy(trojkat)
                trojkat_kopia.append(potomek)
                lista_trojkatow = self.szukaj_z_punktu(potomek, trojkat_kopia, lista_trojkatow)

        return lista_trojkatow


if __name__ == "__main__":

    s = Structure()

    for source_point in range(s.wez_liczbe_punktow()):

        for destination_point in s.wez_punkt(source_point).lista_punktow_docelowych():

            print(f"{source_point} -> {destination_point} = {s.wez_punkt(source_point).wez_kolor_punktu_docelowego(destination_point)}")

    color = "green"

    searching = Search(s)

    number_of_triangles, all_triangles = searching.szukaj("green")

    print(f"Number of triangles of color {color} = {number_of_triangles}")

    print(f"List of all triangles: {all_triangles}")