├── .gitignore
├── .idea
├── .gitignore
├── algoritmi.iml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── other.xml
└── vcs.xml
├── alberi
├── __init__.py
├── abr.py
├── alberibinari.py
├── eccezioni.py
├── test.py
└── utility.py
├── backtracking
├── __init__.py
├── backtracking.py
├── cricca.py
└── subsetsum.py
├── esempigreedy
├── __init__.py
└── knapsackfrazionario.py
├── grafi
├── __init__.py
├── algosugrafi.py
├── algosugrafipesati.py
├── grafi.py
├── grafino.py
├── grafinopesati.py
├── grafipesati.py
├── scheduleratt.py
├── test.py
└── unionfind.py
├── heap
├── __init__.py
├── eccezioni.py
├── heap.py
├── heapmodificabile.py
└── test.py
├── main.py
├── programmazionedinamica
├── __init__.py
├── editdistance.py
├── knapsack01.py
└── lcs.py
└── semplici
├── __init__.py
├── codeprioritafissata.py
├── mergesort.py
├── quicksort.py
├── simple.py
└── test.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Project exclude paths
2 | /env/
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /../../../../../../:\Users\sfles\PycharmProjects\algoritmi\.idea/dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/.idea/algoritmi.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/other.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/alberi/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/alberi/__init__.py
--------------------------------------------------------------------------------
/alberi/abr.py:
--------------------------------------------------------------------------------
1 | from alberi.alberibinari import AlberoBin
2 |
3 |
4 | class ABR:
5 | def __init__(self):
6 | self.valori: AlberoBin = None
7 |
8 | def search(self, val):
9 | x = self.__search__(self.valori, val)
10 | if x is None:
11 | return False
12 | if x.val == val:
13 | return True
14 | return False
15 |
16 | def __search__(self, curr,
17 | val) -> AlberoBin: # restituisce il nodo in cui è contenuto il valore cercato oppure il padre del nodo in cui sarebbe contenuto il valore cercato se non presente
18 | if curr is None:
19 | return curr
20 | if curr.val == val:
21 | return curr
22 | elif curr.val > val:
23 | if curr.sin is not None:
24 | return self.__search__(curr.sin, val)
25 | else:
26 | return curr
27 | else:
28 | if curr.des is not None:
29 | return self.__search__(curr.des, val)
30 | else:
31 | return curr
32 |
33 | def min(self):
34 | if self.valori is None:
35 | return None
36 | curr = self.valori
37 | while curr.sin is not None:
38 | curr = curr.sin
39 | return curr.val
40 |
41 | def max(self):
42 | if self.valori is None:
43 | return None
44 | curr = self.valori
45 | while curr.des is not None:
46 | curr = curr.des
47 | return curr.val
48 |
49 | def insert(self, val):
50 | n = self.__search__(self.valori, val)
51 | if n is None: # Inserimento sulla radice
52 | self.valori = AlberoBin(val)
53 | else:
54 | if n.val != val: # Inserimento generale
55 | nuovo = AlberoBin(val)
56 | if n.val > val:
57 | n.setfigliosin(nuovo)
58 | else:
59 | n.setfigliodes(nuovo)
60 |
61 | def delete(self, val):
62 | if self.valori is None:
63 | return
64 | n = self.__search__(self.valori, val)
65 | if n.val != val:
66 | return
67 | if (n.sin is not None) and (n.des is not None):
68 | tt = n.des
69 | while tt.sin is not None:
70 | tt = tt.sin
71 | n.val = tt.val
72 | n = tt
73 | padre = n.parent
74 | if padre is None:
75 | if n.sin is not None:
76 | self.valori = n.sin
77 | n.sin.pota()
78 | else:
79 | self.valori = n.des
80 | n.des.pota()
81 | else:
82 | if n.sin is not None:
83 | xx = n.sin
84 | else
85 | xx = n.des
86 | xx.pota()
87 | if padre.sin == n:
88 | n.pota()
89 | padre.sin = xx
90 | else:
91 | n.pota()
92 | padre.des = xx
93 |
--------------------------------------------------------------------------------
/alberi/alberibinari.py:
--------------------------------------------------------------------------------
1 | from re import match
2 |
3 | from alberi.eccezioni import ValoriScorretti
4 |
5 |
6 | class AlberoBin:
7 | def __init__(self, val):
8 | self.val = val
9 | self.sin: AlberoBin = None
10 | self.des: AlberoBin = None
11 | self.parent: AlberoBin = None
12 |
13 | def setfigliosin(self, sin):
14 | # complessità: indichiamo com n il numero di nodi già memorizzati nell'albero
15 | # theta(1)
16 | if not isinstance(sin, AlberoBin):
17 | raise ValoriScorretti("tipo figlio non consentito")
18 | if sin is None:
19 | return
20 | if sin.parent is not None:
21 | raise ValoriScorretti("Il figlio passato ha già un padre")
22 | if self.sin is not None:
23 | self.sin.pota() # staccare il figlio esistente
24 | sin.parent = self
25 | self.sin = sin
26 |
27 | def setfigliodes(self, des):
28 | # complessità: indichiamo com n il numero di nodi già memorizzati nell'albero
29 | # theta(1)
30 | if not isinstance(des, AlberoBin):
31 | raise ValoriScorretti("tipo figlio non consentito")
32 | if self.des is not None:
33 | self.des.pota()
34 | if des.parent is not None:
35 | raise ValoriScorretti("Il figlio passato ha già un padre")
36 | des.parent = self
37 | self.des = des
38 |
39 | def pota(self):
40 | # complessità: indichiamo com n il numero di nodi già memorizzati nell'albero
41 | # theta(1)
42 | if self.parent is None:
43 | return
44 | if self.parent.sin == self:
45 | self.parent.sin = None
46 | if self.parent.des == self:
47 | self.parent.des = None
48 | self.parent = None
49 |
50 | def __iter__(self):
51 | self.cur = self
52 | self.hasnext = True
53 | while self.cur.sin is not None:
54 | self.cur = self.cur.sin
55 | return self
56 |
57 | def __next__(self):
58 | if not self.hasnext:
59 | raise StopIteration
60 | tmp = self.cur.val
61 | self.__avanza__()
62 | return tmp
63 |
64 | def __avanza__(self):
65 | direzione = "des"
66 | while direzione != "stop":
67 | match direzione:
68 | case "sin":
69 | if self.cur.sin is None:
70 | direzione = "stop"
71 | else:
72 | self.cur = self.cur.sin
73 | direzione = "sin"
74 | case "des":
75 | if self.cur.des is None:
76 | direzione = "su"
77 | else:
78 | self.cur = self.cur.des
79 | direzione = "sin"
80 | case "su":
81 | if self.cur.parent is None:
82 | self.hasnext = False
83 | direzione = "stop"
84 | else:
85 | if self.cur.parent.sin == self.cur:
86 | self.cur = self.cur.parent
87 | direzione = "stop"
88 | else:
89 | self.cur = self.cur.parent
90 | direzione = "su"
91 |
92 | def visitainfissa(self, l):
93 | if self.sin is not None:
94 | self.sin.visitainfissa(l)
95 | l.append(self.val)
96 | if self.des is not None:
97 | self.des.visitainfissa(l)
98 |
99 | def visitaanticipata(self, l):
100 | l.append(self.val)
101 | if self.sin is not None:
102 | self.sin.visitaanticipata(l)
103 | if self.des is not None:
104 | self.des.visitaanticipata(l)
105 |
106 | def visitaposticipata(self, l):
107 | if self.sin is not None:
108 | self.sin.visitaposticipata(l)
109 | if self.des is not None:
110 | self.des.visitaposticipata(l)
111 | l.append(self.val)
112 |
113 | def visitalivelli(self, l):
114 | coda = [self]
115 | while len(coda) != 0:
116 | curr = coda.pop(0)
117 | l.append(curr.val)
118 | if curr.sin is not None:
119 | coda.append(curr.sin)
120 | if curr.des is not None:
121 | coda.append(curr.des)
122 | return l
123 |
124 |
125 | def tonestedlist(a):
126 | if a is None:
127 | return None
128 | return [a.val, tonestedlist(a.sin), tonestedlist(a.des)]
129 |
130 |
131 | def fromnestedlist(l):
132 | if l is None:
133 | return None
134 | x = AlberoBin(l[0])
135 | s = fromnestedlist(l[1])
136 | if s is not None:
137 | x.setfigliosin(s)
138 | d = fromnestedlist(l[2])
139 | if d is not None:
140 | x.setfigliodes(d)
141 | return x
142 |
--------------------------------------------------------------------------------
/alberi/eccezioni.py:
--------------------------------------------------------------------------------
1 | class ValoriScorretti(Exception):
2 | def __init__(self, message):
3 | self.message = message
--------------------------------------------------------------------------------
/alberi/test.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | from alberi.alberibinari import AlberoBin, tonestedlist, fromnestedlist
4 |
5 | a = AlberoBin(0)
6 | b = AlberoBin(1)
7 | c = AlberoBin(2)
8 | d = AlberoBin(3)
9 | e = AlberoBin(4)
10 | f = AlberoBin(5)
11 | a.setfigliosin(b)
12 | a.setfigliodes(c)
13 | b.setfigliosin(d)
14 | b.setfigliodes(e)
15 | c.setfigliosin(f)
16 | # for x in a:
17 | # print(x)
18 |
19 | l = []
20 | a.visitainfissa(l)
21 | print(l)
22 |
23 | l = []
24 | a.visitaanticipata(l)
25 | print(l)
26 |
27 | l = []
28 | a.visitaposticipata(l)
29 | print(l)
30 |
31 | l = []
32 | a.visitalivelli(l)
33 | print(l)
34 |
35 |
36 | def vI1(a):
37 | l = []
38 | vI(a, l)
39 | return l
40 |
41 |
42 | def vI(a, l):
43 | if a is None:
44 | return
45 | vI(a.sin, l)
46 | l.append(a.val)
47 | vI(a.des, l)
48 |
49 |
50 | def somma(a: AlberoBin)->int:
51 | if a is None:
52 | return 0
53 | return a.val+somma(a.sin)+somma(a.des)
54 |
55 |
56 | def verifica(a: AlberoBin) -> bool:
57 | if a is None:
58 | return False
59 | if a.sin is None and a.des is None:
60 | return False
61 | return verifica(a.sin) or verifica(a.des) or (a.val == somma(a.sin) + somma(a.des))
62 |
63 | def mini(a:AlberoBin)->int:
64 | if(a is None):
65 | return -sys.maxint
66 | minimo = a.val
67 | if(a.sin is not None):
68 | minimo = min(minimo, mini(a.sin))
69 | if(a.des is not None):
70 | minimo = min(minimo,mini(a.des))
71 | return minimo
72 |
73 | def maxi(a:AlberoBin)->int:
74 | if(a is None):
75 | return sys.maxint
76 | massimo = a.val
77 | if(a.sin is not None):
78 | massimo = max(massimo, maxi(a.sin))
79 | if(a.des is not None):
80 | massimo = max(massimo,maxi(a.des))
81 | return massimo
82 |
83 | def ediricercaminmax(a:AlberoBin,mini:int,maxi:int)->bool:
84 | if a is None:
85 | return True
86 | return (mini<=a.val and a.val <= maxi) and \
87 | ediricercaminmax(a.sin,mini, a.val-1) and ediricercaminmax(a.des,a.val+1,maxi)
88 |
89 |
90 | def ediricerca(a:AlberoBin)->bool:
91 | if a is None:
92 | return True
93 | return ediricercaminmax(a,mini(a),maxi(a))
94 |
95 | def sonosimmetrici(a:AlberoBin,b:AlberoBin)->bool:
96 | if a is None and b is None:
97 | return True
98 | if (a is not None and b is None) or (a is None and b is not None):
99 | return False
100 | return a.val==b.val and sonosimmetrici(a.sin,b.des) and sonosimmetrici(a.des, b.sin)
101 |
102 | def esimmetrico(a:AlberoBin)->bool:
103 | return sonosimmetrici(a,a)
104 |
105 |
106 |
107 | lalb = tonestedlist(a)
108 | print(lalb)
109 |
110 | alb = fromnestedlist([0, [1, [3, None, None], [4, None, None]], [1, [5, None, None], None]])
111 | print(tonestedlist(alb))
112 | print(esimmetrico(alb))
113 |
114 | alb = fromnestedlist([0, [1, [3, None, None], [4, None, None]], [1, [4, None, None], [3, None, None]]])
115 | print(tonestedlist(alb))
116 | print(esimmetrico(alb))
117 |
118 | alb.ciccio = "ciao"
119 | print(alb.ciccio)
120 |
--------------------------------------------------------------------------------
/alberi/utility.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from platform import android_ver
3 |
4 | from alberi.abr import ABR
5 | from alberi.alberibinari import AlberoBin
6 |
7 |
8 | def altezza(a: AlberoBin) ->int:
9 | if a is None:
10 | return 0
11 | return 1 + max(altezza(a.sin),altezza(a.des))
12 |
13 | def _xor(a:int, b: int)-> int:
14 | return a+b if a+b<=2 else 2
15 |
16 |
17 | def verifica(a: AlberoBin) ->int:
18 | if a is None:
19 | return 0
20 | if not a.sin and not a.des:
21 | return 1 if a.val == 0 else 0
22 | return _xor(verifica(a.sin), verifica(a.des))
23 |
24 | def verificacorretta(a: AlberoBin) ->bool:
25 | return verifica(a)==1
26 |
27 | menoinfinito = -sys.maxsize
28 |
29 | def massimo(a: AlberoBin)->int:
30 | if a is None:
31 | return menoinfinito
32 | return max(a.val,massimo(a.sin),massimo(a.des))
33 |
34 | def verifica1(a: AlberoBin)->bool:
35 | if a is None or (a.sin is None and a.des is None):
36 | return True
37 | return massimo(a.sin)bool:
41 | if a is None:
42 | return False
43 | if not a.sin and not a.des:
44 | return a.val == val
45 | return almenounafoglia(a.sin, val) or almenounafoglia(a.des, val)
46 |
47 |
48 | def tuttiminori(a:AlberoBin, val)->bool:
49 | if a is None:
50 | return True
51 | return a.valbool:
55 | if a is None:
56 | return True
57 | return a.val>=val and tuttimaggiori(a.sin, val) and tuttimaggiori(a.des, val)
58 |
59 |
60 | def diricerca(a: AlberoBin)->bool:
61 | if a is None:
62 | return True
63 | return (tuttiminori(a.sin, a.val) and tuttimaggiori(a.des, a.val)
64 | and diricerca(a.sin) and diricerca(a.des))
65 |
66 |
67 | def diricercasbagliato(a: AlberoBin)->bool:
68 | if a is None:
69 | return True
70 | if (a.sin is not None):
71 | if a.sin.val >= val:
72 | return False
73 | if (a.des is not None):
74 | if a.des.val >= val:
75 | return False
76 | return diricercasbagliato(a.sin) and diricercasbagliato(a.des)
77 |
78 | def costruisciABRdavettoreordinato(abr:ABR, l:list, inizio: int, fine:int):
79 | if finebool:
6 | liv: int = 0
7 | rivedi: bool = False
8 | if not self.primaScelta(liv):
9 | return False
10 | while liv >= 0:
11 | if self.verificaVincoli(liv):
12 | if self.solCompleta(liv):
13 | self.costruisciSoluzione(liv)
14 | return True
15 | liv += 1
16 | if not self.primaScelta(liv):
17 | rivedi = True
18 | else:
19 | if not self.successivaScelta(liv):
20 | rivedi = True
21 | while rivedi and liv >= 0:
22 | liv -= 1
23 | if liv >= 0 and self.successivaScelta(liv):
24 | rivedi = False
25 | return False
26 |
27 | def primaScelta(self, liv: int)->bool:
28 | pass
29 |
30 | def successivaScelta(self, liv: int)->bool:
31 | pass
32 |
33 | def solCompleta(self, liv: int)->bool:
34 | pass
35 |
36 | def verificaVincoli(self, liv: int)->bool:
37 | pass
38 |
39 | def costruisciSoluzione(self, liv: int):
40 | pass
41 |
--------------------------------------------------------------------------------
/backtracking/cricca.py:
--------------------------------------------------------------------------------
1 | from backtracking import ProblemaBack
2 | from grafi.grafino import GrafoNO, GrafoMANO
3 |
4 |
5 | class Cricca(ProblemaBack):
6 | def __init__(self, g: GrafoNO, k: int):
7 | self.g: Grafo = g
8 | self.nodes: list[int] = [-1 for i in range(k)]
9 | self.sol: list[int] = []
10 |
11 | def primaScelta(self, liv: int) -> bool:
12 | if liv == 0:
13 | self.nodes[liv] = 0
14 | return True
15 | if self.nodes[liv - 1] >= self.g.n - 1:
16 | return False
17 | self.nodes[liv] = self.nodes[liv - 1] + 1
18 | return True
19 |
20 | def successivaScelta(self, liv: int) -> bool:
21 | if self.nodes[liv] >= self.g.n - 1:
22 | return False
23 | self.nodes[liv] = self.nodes[liv] + 1
24 | return True
25 |
26 | def solCompleta(self, liv: int) -> bool:
27 | return liv == len(self.nodes) - 1
28 |
29 | def verificaVincoli(self, liv: int) -> bool:
30 | for i in range(liv - 1):
31 | if not self.g.arco(self.nodes[i], self.nodes[liv]):
32 | return False
33 | return True
34 |
35 | def costruisciSoluzione(self, liv: int):
36 | for x in self.nodes:
37 | self.sol.append(x)
38 |
39 |
40 | g: GrafoNO = GrafoMANO(6)
41 | g.aggiungiarco(0,1)
42 | g.aggiungiarco(1,4)
43 | g.aggiungiarco(0,4)
44 | g.aggiungiarco(2,1)
45 | g.aggiungiarco(1,5)
46 | g.aggiungiarco(3,4)
47 | g.stampa()
48 |
49 | c:Cricca = Cricca(g,3)
50 | if c.risolvi():
51 | print("Cricca(g,3)")
52 | print(c.sol)
53 | else:
54 | print("Cricca(g,3): no sol")
55 |
56 | c:Cricca = Cricca(g,4)
57 | if c.risolvi():
58 | print("Cricca(g,4)")
59 | print(c.sol)
60 | else:
61 | print("Cricca(g,4): no sol")
62 |
--------------------------------------------------------------------------------
/backtracking/subsetsum.py:
--------------------------------------------------------------------------------
1 | from backtracking import ProblemaBack
2 |
3 |
4 | class SubsetSum(ProblemaBack):
5 | def __init__(self, s: list[int], v: int):
6 | super().__init__()
7 | self.s = s
8 | self.v = v
9 | self.sol = [True for i in range(len(s))]
10 | self.soluzione = []
11 |
12 | def primaScelta(self, liv: int)->bool:
13 | if liv == len(self.s):
14 | return False
15 | else:
16 | self.sol[liv] = True
17 | return True
18 |
19 | def successivaScelta(self, liv: int)->bool:
20 | if self.sol[liv]:
21 | self.sol[liv] = False
22 | return True
23 | else:
24 | return False
25 |
26 | def solCompleta(self, liv: int)->bool:
27 | somma =0
28 | for i in range(liv+1):
29 | if self.sol[i]:
30 | somma += self.s[i]
31 | return somma == self.v
32 |
33 | def verificaVincoli(self, liv: int)->bool:
34 | somma = 0
35 | for i in range(liv + 1):
36 | if self.sol[i]:
37 | somma += self.s[i]
38 | return somma <= self.v
39 |
40 | def costruisciSoluzione(self, liv: int):
41 | for i in range(liv + 1):
42 | if self.sol[i]:
43 | self.soluzione.append(self.s[i])
44 | s = [1,21,3,40,13,15,7,8,9,10]
45 | v = 180
46 | p:SubsetSum = SubsetSum(s, v)
47 | if p.risolvi():
48 | print(f"SubsetSum({s}, {v})")
49 | print(f"{p.soluzione} - {sum(p.soluzione)}")
50 | else:
51 | print("SubsetSum(s,v): no sol")
52 |
--------------------------------------------------------------------------------
/esempigreedy/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/esempigreedy/__init__.py
--------------------------------------------------------------------------------
/esempigreedy/knapsackfrazionario.py:
--------------------------------------------------------------------------------
1 | # Python3 program to solve fractional
2 | # Knapsack Problem
3 |
4 |
5 | class ItemValue:
6 | """Item Value DataClass"""
7 |
8 | def __init__(self, wt, val, ind):
9 | self.wt = wt
10 | self.val = val
11 | self.ind = ind
12 | self.cost = val // wt
13 |
14 | def __lt__(self, other):
15 | return self.cost < other.cost
16 |
17 |
18 | # Greedy Approach
19 | class FractionalKnapSack:
20 | """Time Complexity O(n log n)"""
21 |
22 | @staticmethod
23 | def getmaxvalue(wt, val, capacity):
24 | """function to get maximum value """
25 | iVal = []
26 | for i in range(len(wt)):
27 | iVal.append(ItemValue(wt[i], val[i], i))
28 |
29 | # sorting items by value
30 | iVal.sort(reverse=True)
31 |
32 | totalValue = 0
33 | for i in iVal:
34 | curWt = int(i.wt)
35 | curVal = int(i.val)
36 | if capacity - curWt >= 0:
37 | capacity -= curWt
38 | totalValue += curVal
39 | else:
40 | fraction = capacity / curWt
41 | totalValue += curVal * fraction
42 | capacity = int(capacity - (curWt * fraction))
43 | break
44 | return totalValue
45 |
46 |
47 | # Driver Code
48 | if __name__ == "__main__":
49 | wt = [10, 40, 20, 30]
50 | val = [60, 40, 100, 120]
51 | capacity = 50
52 |
53 | # Function call
54 | maxValue = FractionalKnapSack.getmaxvalue(wt, val, capacity)
55 | print("Maximum value in Knapsack =", maxValue)
56 |
57 | # This code is contributed by vibhu4agarwal
58 |
--------------------------------------------------------------------------------
/grafi/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/grafi/__init__.py
--------------------------------------------------------------------------------
/grafi/algosugrafi.py:
--------------------------------------------------------------------------------
1 | from grafi import Grafo, GrafoLA, GrafoMA
2 | from grafino import GrafoNO, GrafoLANO, GrafoMANO
3 |
4 |
5 | def __visitaprofonditaRic__(g: Grafo, nodo: int, visitati: list[bool], risultato: list[int]):
6 | if not visitati[nodo]:
7 | visitati[nodo] = True
8 | risultato.append(nodo)
9 | for ad in g.adiacenti(nodo):
10 | __visitaprofonditaRic__(g, ad, visitati, risultato)
11 |
12 |
13 | def visitaprofonditaRic(g: Grafo, nodo: int) -> list[int]:
14 | risultato: list[int] = []
15 | __visitaprofonditaRic__(g, nodo, [False for i in range(g.n)], risultato)
16 | return risultato
17 |
18 |
19 | def visitaprofondita(g: Grafo, nodo: int) -> list[int]: # MA theta(n^2) LA theta(m) spaziale theta(n)
20 | risultato: list[int] = []
21 | pila: list[int] = []
22 | visitati: list[bool] = [False for i in range(g.n)]
23 | pila.append(nodo)
24 | while pila:
25 | curr: int = pila.pop()
26 | if not visitati[curr]:
27 | visitati[curr] = True
28 | risultato.append(curr)
29 | for ad in reversed(list(g.adiacenti(curr))):
30 | pila.append(ad)
31 | return risultato
32 |
33 |
34 | def visitaampiezza(g: Grafo, nodo: int) -> list[int]: # MA theta(n^2) LA theta(m) spaziale theta(n)
35 | risultato: list[int] = []
36 | coda: list[int] = []
37 | visitati: list[bool] = [False for i in range(g.n)]
38 | coda.append(nodo)
39 | while coda:
40 | curr: int = coda.pop(0) # theta(n)
41 | if not visitati[curr]:
42 | visitati[curr] = True # theta(n)
43 | risultato.append(curr) # theta(n)
44 | for ad in g.adiacenti(curr): # LA theta(m) MA theta(n^2)
45 | if not visitati[ad]: # theta(m)
46 | coda.append(ad) # theta(m)
47 | return risultato
48 |
49 |
50 | def econnesso(g: GrafoNO) -> bool:
51 | result = visitaampiezza(g, 0)
52 | if len(result) == g.n:
53 | return True
54 | return False
55 |
56 |
57 | def ealbero(g: GrafoNO) -> bool: # MA theta(n^2) LA theta(n)
58 | return g.n == g.m + 1 and econnesso(g)
59 |
60 |
61 | def numcompconnesse(g: GrafoNO) -> int:
62 | visitati: list[bool] = [False for i in range(g.n)]
63 | comp: int = 0
64 | for i in range(g.n):
65 | if not visitati[i]:
66 | comp += 1
67 | __visitaprofonditaRic__(g, i, visitati, [])
68 | return comp
69 |
70 |
71 | def eaciclico(g: GrafoNO) -> bool:
72 | return g.n == g.m + numcompconnesse(g)
73 |
74 |
75 | def trovazero(gradi: list[int], rimossi) -> int:
76 | for i in range(len(gradi)):
77 | if gradi[i] == 0 and not rimossi[i]:
78 | return i
79 | return -1
80 |
81 |
82 | def tuttizero(gradi: list[int]) -> bool:
83 | for x in gradi:
84 | if x != 0:
85 | return False
86 | return True
87 |
88 |
89 | def eaciclicoOR(g: Grafo) -> bool: #theta(n^2)
90 | gradi: list[int] = [0 for i in range(g.n)] #theta(n)
91 | rimossi: list[bool] = [False for i in range(g.n)] #theta(n)
92 | for x, y in g.archi(): #MA theta(n^2) LA theta(m)
93 | gradi[y] += 1
94 | curr = trovazero(gradi, rimossi) #theta(n)
95 | while curr != -1: #per ogni nodo che rimuovo (nel caso peggiore per ogni nodo) theta(n^2)
96 | rimossi[curr] = True
97 | for ad in g.adiacenti(curr): #MA theta(n) LA theta(grado_i(curr))
98 | gradi[ad] -= 1
99 | curr = trovazero(gradi, rimossi) #theta(n)
100 | return tuttizero(gradi) #theta(n)
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/grafi/algosugrafipesati.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | from grafipesati import GrafoP, GrafoLAP
4 | from grafinopesati import GrafoNOP, GrafoNOLAP
5 | from heap.heapmodificabile import HeapModificabile
6 | from unionfind import UnionFind
7 |
8 |
9 | def _peso(elem):
10 | return elem[2]
11 |
12 |
13 | class Pair:
14 | def __init__(self, x, p):
15 | self.x = x
16 | self.p = p
17 |
18 | def __lt__(self, other):
19 | return self.p < other.p
20 |
21 | def __eq__(self, other):
22 | return self.x == other.x
23 |
24 | def __hash__(self):
25 | return self.x
26 |
27 | def print(self):
28 | print("(" + str(self.x) + ", " + str(self.p) + ")")
29 |
30 | def __str__(self):
31 | return "(" + str(self.x) + ", " + str(self.p) + ")"
32 |
33 | def __repr__(self):
34 | return "(" + str(self.x) + ", " + str(self.p) + ")"
35 |
36 |
37 | def kruskal(g: GrafoNOP):
38 | archiordinati = sorted(g.archi(), key=_peso)
39 | forest: UnionFind = UnionFind(g.n)
40 | result = []
41 | count = 0
42 | for x, y, p in archiordinati:
43 | if forest.find(x) != forest.find(y):
44 | result.append((x, y, p))
45 | forest.union(forest.find(x), forest.find(y))
46 | count += 1
47 | if count == g.n - 1:
48 | return result
49 | return []
50 |
51 |
52 | def prim(g: GrafoNOP):
53 | padri: list[int] = [-1 for i in range(g.n)]
54 | pesi: list[int] = [sys.maxsize for i in range(g.n)]
55 | preso: list[bool] = [False for i in range(g.n)]
56 | curr: int = 0
57 | padri[0] = 0
58 | preso[0] = True
59 | count = 1
60 | result = []
61 | mioheap: HeapModificabile = HeapModificabile(g.n)
62 | for a in g.adiacenti(curr):
63 | mioheap.ins(Pair(a.y, a.peso))
64 | padri[a.y] = curr
65 | pesi[a.y] = a.peso
66 | while not mioheap.evuoto():
67 | count += 1
68 | cp: Pair = mioheap.out()
69 | preso[cp.x] = True
70 | result.append((padri[cp.x], cp.x, cp.p))
71 | for a in g.adiacenti(cp.x):
72 | if not preso[a.y]:
73 | if padri[a.y] == -1:
74 | mioheap.ins(Pair(a.y, a.peso))
75 | padri[a.y] = cp.x
76 | pesi[a.y] = a.peso
77 | elif pesi[a.y] > a.peso:
78 | mioheap.update(Pair(a.y, a.peso))
79 | padri[a.y] = cp.x
80 | pesi[a.y] = a.peso
81 | if count == g.n:
82 | return result
83 | else:
84 | return []
85 |
86 |
87 | def Dijkstra(g: GrafoP, source: int):
88 | padri: list[int] = [-1 for i in range(g.n)]
89 | pesi: list[int] = [sys.maxsize for i in range(g.n)]
90 | preso: list[bool] = [False for i in range(g.n)]
91 | curr: int = source
92 | padri[curr] = curr
93 | preso[curr] = True
94 | count = 1
95 | result = []
96 | mioheap: HeapModificabile = HeapModificabile(g.n)
97 | for a in g.adiacenti(curr):
98 | mioheap.ins(Pair(a.y, a.peso))
99 | padri[a.y] = curr
100 | pesi[a.y] = a.peso
101 | while not mioheap.evuoto():
102 | count += 1
103 | cp: Pair = mioheap.out()
104 | preso[cp.x] = True
105 | result.append((padri[cp.x], cp.x, cp.p))
106 | for a in g.adiacenti(cp.x):
107 | if not preso[a.y]:
108 | if padri[a.y] == -1:
109 | mioheap.ins(Pair(a.y, a.peso + pesi[cp.x]))
110 | padri[a.y] = cp.x
111 | pesi[a.y] = a.peso
112 | elif pesi[a.y] > a.peso + pesi[cp.x]:
113 | mioheap.update(Pair(a.y, a.peso + pesi[cp.x]))
114 | padri[a.y] = cp.x
115 | pesi[a.y] = a.peso
116 | return result
117 |
118 |
119 | def floyd(g: GrafoP):
120 | M = [[sys.maxsize for i in range(g.n)] for j in range(g.n)] # Calcola matrice di adiacenza
121 | for i in range(g.n):
122 | M[i][i] = 0
123 | for x, y, p in g.archi():
124 | M[x][y] = p
125 | for x in range(len(M)):
126 | for u in range(len(M)):
127 | for v in range(len(M)):
128 | if M[u][v] > M[u][x] + M[x][v]:
129 | M[u][v] = M[u][x] + M[x][v]
130 | return M
131 |
132 |
133 | g = GrafoLAP(5)
134 | g.aggiungiarco(0, 1, 2.1)
135 | g.aggiungiarco(0, 2, 1.1)
136 | g.aggiungiarco(1, 2, 1)
137 | g.aggiungiarco(3, 0, 1)
138 | g.aggiungiarco(3, 4, 1.2)
139 | g.aggiungiarco(0, 4, 2.2)
140 | g.stampa()
141 |
142 | # print(kruskal(g))
143 | # print(prim(g))
144 |
145 | print(floyd(g))
146 |
--------------------------------------------------------------------------------
/grafi/grafi.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 |
4 | class Grafo:
5 | def __init__(self, n: int):
6 | self.n: int = n
7 | self.m: int = 0
8 |
9 | def aggiungiarco(self, x, y):
10 | pass
11 |
12 | def rimuoviarco(self, x, y):
13 | pass
14 |
15 | def arco(self, x, y):
16 | pass
17 |
18 | def adiacenti(self, x):
19 | pass
20 |
21 | def archi(self):
22 | pass
23 |
24 | def stampa(self):
25 | pass
26 |
27 |
28 | class GrafoMA(Grafo):
29 | def __init__(self, n): # crea un grafo con numero di nodi nodes
30 | super().__init__(n)
31 | self.mat = np.zeros((n, n), np.bool_)
32 |
33 | def aggiungiarco(self, x: int, y: int): #theta(1)
34 | if not self.mat[x][y]:
35 | self.mat[x][y] = True
36 | self.m += 1
37 |
38 | def rimuoviarco(self, x: int, y: int): #theta(1)
39 | if self.mat[x][y]:
40 | self.mat[x][y] = False
41 | self.m -= 1
42 |
43 | def arco(self, x: int, y: int) -> bool: #theta(1)
44 | return self.mat[x][y]
45 |
46 | def adiacenti(self, x): #La complessita di scorrere tutto l'iterable è theta(n)
47 | return IterArcoMAAdiacenti(self, x)
48 |
49 | def archi(self): #La complessita di scorrere tutto l'iterable è theta(n^2)
50 | return IterArcoMA(self)
51 |
52 | def stampa(self):
53 | for x in range(self.mat.shape[0]):
54 | for y in range(self.mat.shape[1]):
55 | if self.mat[x][y]:
56 | print("(" + str(x) + ", " + str(y) + ")")
57 |
58 |
59 | class IterArcoMAAdiacenti:
60 | def __init__(self, g, x):
61 | self.g = g
62 | self.x = x
63 |
64 | def __iter__(self):
65 | self.y = 0
66 | while self.y < self.g.mat.shape[1] and not self.g.mat[self.x][self.y]:
67 | self.y += 1
68 | if self.y < self.g.mat.shape[1]:
69 | self.hasnext = True
70 | else:
71 | self.hasnext = False
72 | return self
73 |
74 | def __next__(self):
75 | if not self.hasnext:
76 | raise StopIteration
77 | tmp = self.y
78 | self.y += 1
79 | while self.y < self.g.mat.shape[1] and not self.g.mat[self.x][self.y]:
80 | self.y += 1
81 | if self.y < self.g.mat.shape[1]:
82 | self.hasnext = True
83 | else:
84 | self.hasnext = False
85 | return tmp
86 |
87 |
88 | class IterArcoMA:
89 | def __init__(self, g):
90 | self.g = g
91 |
92 | def __iter__(self):
93 | self.x = 0
94 | self.it = iter(self.g.adiacenti(self.x))
95 | return self
96 |
97 | def __next__(self):
98 | trovato = False
99 | while not trovato:
100 | try:
101 | y = next(self.it)
102 | trovato = True
103 | except StopIteration:
104 | if self.x < self.g.n - 1:
105 | self.x += 1
106 | self.it = iter(self.g.adiacenti(self.x))
107 | else:
108 | raise StopIteration
109 | return self.x, y
110 |
111 |
112 | class GrafoLA(Grafo):
113 | def __init__(self, n): # crea un grafo con numero di nodi nodes
114 | super().__init__(n)
115 | self.mat = [[] for i in range(n)]
116 |
117 | def aggiungiarco(self, x, y): #theta(grado_u(x))
118 | if y not in self.mat[x]:
119 | self.mat[x].append(y)
120 | self.m += 1
121 |
122 | def rimuoviarco(self, x, y):
123 | try:
124 | self.mat[x].remove(y) #theta(grado_u(x))
125 | self.m -= 1
126 | except ValueError:
127 | pass
128 |
129 | def arco(self, x, y): #theta(grado_u(x))
130 | return y in self.mat[x]
131 |
132 | def adiacenti(self, x): #La complessita di scorrere tutto l'iterable è theta(grado_u(x))
133 | return self.mat[x]
134 |
135 | def archi(self): #La complessita di scorrere tutto l'iterable è theta(m)
136 | return IterArcoLA(self)
137 |
138 | def stampa(self):
139 | for x in range(len(self.mat)):
140 | for y in self.mat[x]:
141 | print("(" + str(x) + ", " + str(y) + ")")
142 |
143 |
144 | class IterArcoLA:
145 | def __init__(self, g):
146 | self.g: GrafoLA = g
147 |
148 | def __iter__(self):
149 | self.x = 0
150 | self.it = iter(self.g.adiacenti(self.x))
151 | return self
152 |
153 | def __next__(self):
154 | trovato = False
155 | while not trovato:
156 | try:
157 | y = next(self.it)
158 | trovato = True
159 | except StopIteration:
160 | if self.x < self.g.n - 1:
161 | self.x += 1
162 | self.it = iter(self.g.adiacenti(self.x))
163 | else:
164 | raise StopIteration
165 | return self.x, y
166 |
--------------------------------------------------------------------------------
/grafi/grafino.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | class GrafoNO:
4 | def __init__(self,n:int):
5 | self.n = n
6 | self.m = 0
7 |
8 | def aggiungiarco(self, x, y):
9 | pass
10 |
11 | def rimuoviarco(self, x, y):
12 | pass
13 |
14 | def arco(self, x, y):
15 | pass
16 |
17 | def adiacenti(self, x):
18 | pass
19 |
20 | def archi(self):
21 | pass
22 |
23 | def stampa(self):
24 | pass
25 |
26 |
27 | class GrafoMANO(GrafoNO):
28 | def __init__(self, n): # crea un grafo con numero di nodi nodes
29 | super().__init__(n)
30 | self.mat = np.zeros((n, n), np.bool_)
31 |
32 |
33 | def aggiungiarco(self, x, y):
34 | if not self.mat[x][y]:
35 | self.mat[x][y] = True
36 | self.mat[y][x] = True
37 | self.m += 1
38 |
39 | def rimuoviarco(self, x, y):
40 | if self.mat[x][y]:
41 | self.mat[x][y] = False
42 | self.mat[y][x] = False
43 | self.m -= 1
44 |
45 | def arco(self, x, y):
46 | return self.mat[x][y]
47 |
48 | def adiacenti(self, x):
49 | return IterArcoMAAdiacenti(self, x)
50 |
51 | def archi(self):
52 | return IterArcoMA(self)
53 |
54 | def stampa(self):
55 | for x in range(self.mat.shape[0]):
56 | for y in range(self.mat.shape[1]):
57 | if self.mat[x][y]:
58 | print("(" + str(x) + ", " + str(y) + ")")
59 |
60 |
61 | class IterArcoMAAdiacenti:
62 | def __init__(self, g, x):
63 | self.g = g
64 | self.x = x
65 |
66 | def __iter__(self):
67 | self.y = 0
68 | while self.y < self.g.mat.shape[1] and not self.g.mat[self.x][self.y]:
69 | self.y += 1
70 | if self.y < self.g.mat.shape[1]:
71 | self.hasnext = True
72 | else:
73 | self.hasnext = False
74 | return self
75 |
76 | def __next__(self):
77 | if not self.hasnext:
78 | raise StopIteration
79 | tmp = self.y
80 | self.y += 1
81 | while self.y < self.g.mat.shape[1] and not self.g.mat[self.x][self.y]:
82 | self.y += 1
83 | if self.y < self.g.mat.shape[1]:
84 | self.hasnext = True
85 | else:
86 | self.hasnext = False
87 | return tmp
88 |
89 |
90 | class IterArcoMA:
91 | def __init__(self, g):
92 | self.g = g
93 |
94 | def __iter__(self):
95 | self.x = 0
96 | self.it = iter(self.g.adiacenti(self.x))
97 | return self
98 |
99 | def __next__(self):
100 | trovato = False
101 | while not trovato:
102 | try:
103 | y = next(self.it)
104 | if y >= self.x:
105 | trovato = True
106 | except StopIteration:
107 | if self.x < self.g.n-1:
108 | self.x += 1
109 | self.it = iter(self.g.adiacenti(self.x))
110 | else:
111 | raise StopIteration
112 | return self.x, y
113 |
114 |
115 | class GrafoLANO(GrafoNO):
116 | def __init__(self, n): # crea un grafo con numero di nodi nodes
117 | super().__init__(n)
118 | self.mat = [[] for i in range(n)]
119 |
120 | def aggiungiarco(self, x, y):
121 | if y not in self.mat[x]:
122 | self.mat[x].append(y)
123 | self.mat[y].append(x)
124 | self.m += 1
125 |
126 | def rimuoviarco(self, x, y):
127 | if self.arco(x,y):
128 | self.mat[x].remove(y)
129 | self.mat[y].remove(x)
130 | self.m -=1
131 |
132 | def arco(self, x, y):
133 | return y in self.mat[x]
134 |
135 | def adiacenti(self, x):
136 | return self.mat[x]
137 |
138 | def archi(self):
139 | return IterArcoLA(self)
140 |
141 | def stampa(self):
142 | for x in range(len(self.mat)):
143 | for y in self.mat[x]:
144 | print("(" + str(x) + ", " + str(y) + ")")
145 |
146 | class IterArcoLA:
147 | def __init__(self, g):
148 | self.g:GrafoLA = g
149 |
150 | def __iter__(self):
151 | self.x = 0
152 | self.it = iter(self.g.adiacenti(self.x))
153 | return self
154 |
155 | def __next__(self):
156 | trovato = False
157 | while not trovato:
158 | try:
159 | y = next(self.it)
160 | if y >= self.x:
161 | trovato = True
162 | except StopIteration:
163 | if self.x < self.g.n-1:
164 | self.x += 1
165 | self.it = iter(self.g.adiacenti(self.x))
166 | else:
167 | raise StopIteration
168 | return self.x, y
169 |
170 |
--------------------------------------------------------------------------------
/grafi/grafinopesati.py:
--------------------------------------------------------------------------------
1 | class GrafoNOP:
2 | def __init__(self, n: int):
3 | self.n = n
4 | self.m = 0
5 |
6 | def aggiungiarco(self, x: int, y: int, peso: float):
7 | pass
8 |
9 | def rimuoviarco(self, x: int, y: int):
10 | pass
11 |
12 | def arco(self, x: int, y: int) -> float:
13 | pass
14 |
15 | def adiacenti(self, x: int):
16 | pass
17 |
18 | def archi(self):
19 | pass
20 |
21 | def stampa(self):
22 | pass
23 |
24 |
25 | class CoppiaP:
26 | def __init__(self, y:int, peso:float):
27 | self.y=y
28 | self.peso=peso
29 |
30 | def __eq__(self, other):
31 | if isinstance(other, self.__class__):
32 | return self.y==other.y
33 | return False
34 |
35 | def __ne__(self, other):
36 | return not self.__eq__(other)
37 |
38 | def __repr__(self):
39 | return "(" + str(self.y) + ", " + str(self.peso) + ")"
40 |
41 |
42 | class GrafoNOLAP(GrafoNOP):
43 | def __init__(self, n): # crea un grafo con numero di nodi nodes
44 | super().__init__(n)
45 | self.mat = [[] for i in range(n)]
46 |
47 | def aggiungiarco(self, x: int, y: int, peso: float):
48 | if y not in self.mat[x]:
49 | self.mat[x].append(CoppiaP(y, peso))
50 | self.mat[y].append(CoppiaP(x, peso))
51 | self.m += 1
52 |
53 | def rimuoviarco(self, x, y):
54 | try:
55 | self.mat[x].remove(CoppiaP(y,0))
56 | self.mat[y].remove(CoppiaP(x, 0))
57 | self.m -= 1
58 | except ValueError:
59 | pass
60 |
61 | def arco(self, x, y):
62 | c = self.mat[x][self.mat[x].index(CoppiaP(y,0))]
63 | return x, c.y, c.peso
64 |
65 | def adiacenti(self, x):
66 | return self.mat[x]
67 |
68 | def archi(self):
69 | return IterArcoLA(self)
70 |
71 | def stampa(self):
72 | for x in range(len(self.mat)):
73 | for c in self.mat[x]:
74 | print("(" + str(x) + ", " + str(c.y) + ", "+ str(c.peso) + ")")
75 |
76 |
77 | class IterArcoLA:
78 | def __init__(self, g):
79 | self.g: GrafoLA = g
80 |
81 | def __iter__(self):
82 | self.x = 0
83 | self.it = iter(self.g.adiacenti(self.x))
84 | return self
85 |
86 | def __next__(self):
87 | trovato = False
88 | while not trovato:
89 | try:
90 | c = next(self.it)
91 | trovato = True
92 | except StopIteration:
93 | if self.x < self.g.n - 1:
94 | self.x += 1
95 | self.it = iter(self.g.adiacenti(self.x))
96 | else:
97 | raise StopIteration
98 | return self.x, c.y, c.peso
99 |
100 |
101 |
102 |
103 |
104 |
105 | g = GrafoNOLAP(4)
106 | g.aggiungiarco(0, 1, 2.1)
107 | g.aggiungiarco(0, 2, 1.1)
108 | g.aggiungiarco(1, 2, 1)
109 | g.aggiungiarco(2, 0, 1)
110 | g.aggiungiarco(3, 0, 1)
111 | g.stampa()
112 |
113 | print("\n")
114 | g.rimuoviarco(0,3)
115 | g.stampa()
116 | print("\n")
117 | print(g.arco(0,1))
118 |
119 | print("\n")
120 | for c in g.archi():
121 | print(c)
--------------------------------------------------------------------------------
/grafi/grafipesati.py:
--------------------------------------------------------------------------------
1 | class GrafoP:
2 | def __init__(self, n: int):
3 | self.n = n
4 | self.m = 0
5 |
6 | def aggiungiarco(self, x: int, y: int, peso: float):
7 | pass
8 |
9 | def rimuoviarco(self, x: int, y: int):
10 | pass
11 |
12 | def arco(self, x: int, y: int) -> float:
13 | pass
14 |
15 | def adiacenti(self, x: int):
16 | pass
17 |
18 | def archi(self):
19 | pass
20 |
21 | def stampa(self):
22 | pass
23 |
24 |
25 | class CoppiaP:
26 | def __init__(self, y:int, peso:float):
27 | self.y=y
28 | self.peso=peso
29 |
30 | def __eq__(self, other):
31 | if isinstance(other, self.__class__):
32 | return self.y==other.y
33 | return False
34 |
35 | def __ne__(self, other):
36 | return not self.__eq__(other)
37 |
38 | def __repr__(self):
39 | return "(" + str(self.y) + ", " + str(self.peso) + ")"
40 |
41 |
42 | class GrafoLAP(GrafoP):
43 | def __init__(self, n): # crea un grafo con numero di nodi nodes
44 | super().__init__(n)
45 | self.mat = [[] for i in range(n)]
46 |
47 | def aggiungiarco(self, x: int, y: int, peso: float):
48 | if y not in self.mat[x]:
49 | self.mat[x].append(CoppiaP(y, peso))
50 | self.m += 1
51 |
52 | def rimuoviarco(self, x, y):
53 | try:
54 | self.mat[x].remove(CoppiaP(y,0))
55 | self.m -= 1
56 | except ValueError:
57 | pass
58 |
59 | def arco(self, x, y):
60 | c = self.mat[x][self.mat[x].index(CoppiaP(y,0))]
61 | return x, c.y, c.peso
62 |
63 | def adiacenti(self, x):
64 | return self.mat[x]
65 |
66 | def archi(self):
67 | return IterArcoLA(self)
68 |
69 | def stampa(self):
70 | for x in range(len(self.mat)):
71 | for c in self.mat[x]:
72 | print("(" + str(x) + ", " + str(c.y) + ", "+ str(c.peso) + ")")
73 |
74 |
75 | class IterArcoLA:
76 | def __init__(self, g):
77 | self.g: GrafoLA = g
78 |
79 | def __iter__(self):
80 | self.x = 0
81 | self.it = iter(self.g.adiacenti(self.x))
82 | return self
83 |
84 | def __next__(self):
85 | trovato = False
86 | while not trovato:
87 | try:
88 | c = next(self.it)
89 | trovato = True
90 | except StopIteration:
91 | if self.x < self.g.n - 1:
92 | self.x += 1
93 | self.it = iter(self.g.adiacenti(self.x))
94 | else:
95 | raise StopIteration
96 | return self.x, c.y, c.peso
97 |
98 |
99 |
100 |
101 |
102 |
103 | g = GrafoLAP(4)
104 | g.aggiungiarco(0, 1, 2.1)
105 | g.aggiungiarco(0, 2, 1.1)
106 | g.aggiungiarco(1, 2, 1)
107 | g.aggiungiarco(2, 0, 1)
108 | g.aggiungiarco(3, 0, 1)
109 | g.stampa()
110 |
111 | print("\n")
112 | g.rimuoviarco(0,3)
113 | g.stampa()
114 | print("\n")
115 | print(g.arco(0,1))
116 |
117 | print("\n")
118 | for c in g.archi():
119 | print(c)
--------------------------------------------------------------------------------
/grafi/scheduleratt.py:
--------------------------------------------------------------------------------
1 | from grafi import GrafoLA
2 | from algosugrafi import trovazero, tuttizero
3 |
4 |
5 | class AttivitaNonSchedulabili(Exception):
6 | pass
7 |
8 |
9 | class Attivita:
10 | def __init__(self, nome: str, durata: int):
11 | self.nome: str = nome
12 | self.durata: int = durata
13 | self.start: int = 0
14 |
15 | def __str__(self):
16 | return "("+self.nome+","+self.durata+","+self.start+")"
17 |
18 | def __repr__(self):
19 | return "("+self.nome+","+str(self.durata)+","+str(self.start)+")"
20 |
21 |
22 | class Propedeuticita:
23 | def __init__(self, fromatt: int, toatt: int):
24 | self.fromatt: int = fromatt
25 | self.toatt: int = toatt
26 |
27 |
28 |
29 | class Scheduler:
30 | def __init__(self, listaattivita: list[Attivita], prop: list[Propedeuticita]):
31 | self.atts: list(Attivita) = listaattivita
32 | self.grafo = GrafoLA(len(self.atts))
33 | for p in prop:
34 | self.grafo.aggiungiarco(p.fromatt, p.toatt)
35 |
36 | def addpropedeuticita(self, afrom: int, ato: int):
37 | self.grafo.aggiungiarco(afrom, ato)
38 |
39 | def schedule(self) -> list[Attivita]:
40 | gradi: list[int] = [0 for i in range(self.grafo.n)]
41 | rimossi: list[bool] = [False for i in range(self.grafo.n)]
42 | for x, y in self.grafo.archi():
43 | gradi[y] += 1
44 | curr = trovazero(gradi, rimossi)
45 | while curr != -1:
46 | rimossi[curr] = True
47 | for ad in self.grafo.adiacenti(curr):
48 | gradi[ad] -= 1
49 | if self.atts[ad].start < self.atts[curr].start + self.atts[curr].durata:
50 | self.atts[ad].start = self.atts[curr].start + self.atts[curr].durata
51 | curr = trovazero(gradi, rimossi)
52 | if tuttizero(gradi):
53 | return self.atts
54 | else:
55 | raise AttivitaNonSchedulabili("propedeuticità cicliche")
56 |
--------------------------------------------------------------------------------
/grafi/test.py:
--------------------------------------------------------------------------------
1 | from grafi import GrafoMA
2 | from grafi import GrafoLA, Grafo
3 | from algosugrafi import visitaprofonditaRic, visitaprofondita, visitaampiezza, eaciclicoOR
4 | from grafino import GrafoLANO, GrafoMANO
5 | from unionfind import UnionFind
6 | from scheduleratt import Scheduler, Attivita, Propedeuticita
7 |
8 | g = GrafoMANO(4)
9 | g.aggiungiarco(0, 1)
10 | g.aggiungiarco(0, 2)
11 | g.aggiungiarco(1, 2)
12 | g.aggiungiarco(2, 0)
13 | g.aggiungiarco(3, 0)
14 | g.stampa()
15 |
16 | print("adiacenti di 0")
17 | it = g.adiacenti(0)
18 | for a in it:
19 | print(a)
20 |
21 | print("tutti")
22 | it = g.archi()
23 | for a in it:
24 | print(a)
25 |
26 |
27 | UF = UnionFind(5)
28 | print('UF')
29 | print(UF)
30 | UF.union(UF.find(0), UF.find(1))
31 | print('DOPO UNION Set(0) e Set(1)')
32 | print(UF)
33 | UF.union(UF.find(2), UF.find(1))
34 | print('DOPO UNION Set(2) e Set(1)')
35 | print(UF)
36 |
37 |
38 | g: Grafo = GrafoLA(7)
39 | g.aggiungiarco(0, 1)
40 | g.aggiungiarco(0, 2)
41 | g.aggiungiarco(1, 3)
42 | # g.aggiungiarco(2, 3)
43 | g.aggiungiarco(3, 4)
44 | g.aggiungiarco(5, 6)
45 | g.stampa()
46 |
47 | print(visitaprofonditaRic(g, 0))
48 | print(visitaprofondita(g, 0))
49 | print(visitaampiezza(g, 0))
50 | # print("E' connesso:"+str(econnesso(g)))
51 | # print("E' albero:"+str(ealbero(g)))
52 | # print("Num componenti connesse:"+str(numcompconnesse(g)))
53 | # print("E' aciclico:"+str(eaciclico(g)))
54 | print("E' aciclico:" + str(eaciclicoOR(g)))
55 |
56 |
57 | listatt = [Attivita(str(i), i+1) for i in range(g.n)]
58 | listprop = [Propedeuticita(x,y) for x,y in g.archi()]
59 | schedulatore: Scheduler = Scheduler(listatt,listprop)
60 | listatt = schedulatore.schedule()
61 | print(listatt)
--------------------------------------------------------------------------------
/grafi/unionfind.py:
--------------------------------------------------------------------------------
1 | class MySet:
2 | def __init__(self, elem: int):
3 | self.elementlist: list[int] = [elem]
4 | self.name: int = elem
5 | self.pos: int = self.name
6 | self.size: int = 1
7 |
8 | def __repr__(self):
9 | return "("+str(self.name)+", "+str(self.size)+", "+str(self.pos)+", "+str(self.elementlist) +")"
10 |
11 |
12 | class UnionFind:
13 | def __init__(self, n: int):
14 | self.sets: list = [MySet(i) for i in range(n)]
15 | self.elements: list = [i for i in range(n)]
16 |
17 | def find(self, elem: int) -> MySet:
18 | return self.sets[self.elements[elem]]
19 |
20 | def union(self, a: MySet, b: MySet):
21 | if a.size < b.size:
22 | print('Eseguo '+ str(len(a.elementlist))+' spostamenti')
23 | for el in a.elementlist:
24 | self.elements[el] = b.pos
25 | b.elementlist.append(el)
26 | b.size += a.size
27 | b.name = a.name
28 | a.size = 0
29 | a.elementlist = []
30 | else:
31 | print('Eseguo ' + str(len(b.elementlist)) + ' spostamenti')
32 | for el in b.elementlist:
33 | self.elements[el] = a.pos
34 | a.elementlist.append(el)
35 | a.size += b.size
36 | b.size = 0
37 | b.elementlist = []
38 |
39 |
40 | def unionSenzaBilanciamento(self, a: MySet, b: MySet):
41 | for el in b.elementlist:
42 | self.elements[el] = a.pos
43 | a.elementlist.append(el)
44 | a.size += b.size
45 | b.size = 0
46 | b.elementlist = []
47 |
48 | def __repr__(self):
49 | return str(self.sets)+"\n"+str(self.elements)
50 |
--------------------------------------------------------------------------------
/heap/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/heap/__init__.py
--------------------------------------------------------------------------------
/heap/eccezioni.py:
--------------------------------------------------------------------------------
1 | class HeapFullError(Exception):
2 | def __init__(self, message="Heap pieno"):
3 | self.message = message
--------------------------------------------------------------------------------
/heap/heap.py:
--------------------------------------------------------------------------------
1 | from heap.eccezioni import HeapFullError
2 |
3 |
4 | class Heap:
5 | def __init__(self, dim: int):
6 | self.dim = dim
7 | self.actualdim = 0
8 | self.values = [0 for x in range(dim)]
9 |
10 |
11 |
12 | def ins(self, val):
13 | if self.actualdim < self.dim:
14 | self.values[self.actualdim] = val
15 | curr = self.actualdim
16 | self.actualdim += 1
17 | while curr > 0 and self.values[curr] < self.values[(curr + 1) // 2 - 1]:
18 | tmp = self.values[(curr + 1) // 2 - 1]
19 | self.values[(curr + 1) // 2 - 1] = self.values[curr]
20 | self.values[curr] = tmp
21 | curr = (curr + 1) // 2 - 1
22 | else:
23 | raise HeapFullError()
24 |
25 | def top(self):
26 | if self.actualdim <= 0:
27 | raise HeapEmptyError()
28 | return self.values[0]
29 |
30 | def out(self):
31 | x = self.top()
32 | self.values[0] = self.values[self.actualdim - 1]
33 | self.actualdim -= 1
34 | curr = 0
35 | while (curr + 1) * 2 - 1 < self.actualdim:
36 | if (curr + 1) * 2 < self.actualdim:
37 | if self.values[curr] > min(self.values[(curr + 1) * 2 - 1], self.values[(curr + 1) * 2]):
38 | if self.values[(curr + 1) * 2 - 1] < self.values[(curr + 1) * 2]:
39 | tmp = self.values[curr]
40 | self.values[curr] = self.values[(curr + 1) * 2 - 1]
41 | self.values[(curr + 1) * 2 - 1] = tmp
42 | curr = (curr + 1) * 2 - 1
43 | else:
44 | tmp = self.values[curr]
45 | self.values[curr] = self.values[(curr + 1) * 2]
46 | self.values[(curr + 1) * 2] = tmp
47 | curr = (curr + 1) * 2
48 | else:
49 | break
50 | if self.values[curr] > self.values[(curr + 1) * 2 - 1]:
51 | tmp = self.values[curr]
52 | self.values[curr] = self.values[(curr + 1) * 2 - 1]
53 | self.values[(curr + 1) * 2 - 1] = tmp
54 | curr = (curr + 1) * 2 - 1
55 | else:
56 | break
57 | return x
58 |
59 | def print(self):
60 | print("Numero elementi:" + str(self.actualdim))
61 | print("Dimensione max:" + str(self.dim))
62 | print("Elenco Valori")
63 | print(str(self.values[:self.actualdim]))
64 |
--------------------------------------------------------------------------------
/heap/heapmodificabile.py:
--------------------------------------------------------------------------------
1 | from heap.heap import Heap
2 |
3 |
4 | class HeapModificabile(Heap):
5 |
6 | def __init__(self, dim):
7 | super().__init__(dim)
8 | self.positions = {}
9 |
10 | def ins(self, val):
11 | if self.actualdim < self.dim:
12 | self.values[self.actualdim] = val
13 | curr = self.actualdim
14 | self.positions[val]=curr
15 | self.actualdim +=1
16 | while curr > 0 and self.values[curr] min(self.values[(curr+1) * 2 - 1], self.values[(curr+1) * 2]):
35 | if self.values[(curr+1) * 2 - 1] < self.values[(curr+1) * 2]:
36 | tmp = self.values[curr]
37 | self.values[curr] = self.values[(curr+1) * 2 - 1]
38 | self.values[(curr+1) * 2 - 1] = tmp
39 | self.positions[self.values[curr]] = curr
40 | self.positions[self.values[(curr+1) * 2 - 1]] = (curr+1) * 2 - 1
41 | curr = (curr+1) * 2 - 1
42 | else:
43 | tmp = self.values[curr]
44 | self.values[curr] = self.values[(curr+1) * 2]
45 | self.values[(curr+1) * 2] = tmp
46 | self.positions[self.values[curr]] = curr
47 | self.positions[self.values[(curr+1) * 2]] = (curr+1) * 2
48 | curr = (curr+1) * 2
49 | else:
50 | break
51 | elif self.values[curr] > self.values[(curr + 1) * 2 - 1]:
52 | tmp = self.values[curr]
53 | self.values[curr] = self.values[(curr + 1) * 2 - 1]
54 | self.values[(curr + 1) * 2 - 1] = tmp
55 | self.positions[self.values[curr]] = curr
56 | self.positions[self.values[(curr + 1) * 2 - 1]] = (curr + 1) * 2 - 1
57 | curr = (curr + 1) * 2 - 1
58 | else:
59 | break
60 | del self.positions[x]
61 | return x
62 |
63 | def update(self, val):
64 | if not val in self.positions: #implementazione inefficiente sarebbe necessario un accesso diretto
65 | self.ins(val)
66 | else:
67 | curr = self.positions[val]
68 | if val < self.values[curr]:
69 | self.values[curr] = val
70 | del self.positions[val]
71 | self.positions[val] = curr
72 | while curr > 0 and self.values[curr] < self.values[(curr + 1) // 2 - 1]:
73 | tmp = self.values[(curr + 1) // 2 - 1]
74 | self.values[(curr + 1) // 2 - 1] = self.values[curr]
75 | self.values[curr] = tmp
76 | self.positions[self.values[(curr + 1) // 2 - 1]] = (curr + 1) // 2 - 1
77 | self.positions[self.values[curr]] = curr
78 | curr = (curr + 1) // 2 - 1
79 | else:
80 | self.values[curr] = val
81 | del self.positions[val]
82 | self.positions[val] = curr
83 | while (curr + 1) * 2 - 1 < self.actualdim:
84 | if (curr + 1) * 2 < self.actualdim:
85 | if self.values[curr] > min(self.values[(curr + 1) * 2 - 1], self.values[(curr + 1) * 2]):
86 | if self.values[(curr + 1) * 2 - 1] < self.values[(curr + 1) * 2]:
87 | tmp = self.values[curr]
88 | self.values[curr] = self.values[(curr + 1) * 2 - 1]
89 | self.values[(curr + 1) * 2 - 1] = tmp
90 | self.positions[self.values[curr]] = curr
91 | self.positions[self.values[(curr + 1) * 2 - 1]] = (curr + 1) * 2 - 1
92 | curr = (curr + 1) * 2 - 1
93 | else:
94 | tmp = self.values[curr]
95 | self.values[curr] = self.values[(curr + 1) * 2]
96 | self.values[(curr + 1) * 2] = tmp
97 | self.positions[self.values[curr]] = curr
98 | self.positions[self.values[(curr + 1) * 2]] = (curr + 1) * 2
99 | curr = (curr + 1) * 2
100 | else:
101 | break
102 | if self.values[curr] > self.values[(curr + 1) * 2 - 1]:
103 | tmp = self.values[curr]
104 | self.values[curr] = self.values[(curr + 1) * 2 - 1]
105 | self.values[(curr + 1) * 2 - 1] = tmp
106 | self.positions[self.values[curr]] = curr
107 | self.positions[self.values[(curr + 1) * 2 - 1]] = (curr + 1) * 2 - 1
108 | curr = (curr + 1) * 2 - 1
109 | else:
110 | break
111 |
112 | def evuoto(self):
113 | return self.actualdim==0
114 |
115 | def print(self):
116 | super().print()
117 | print(self.positions)
118 |
--------------------------------------------------------------------------------
/heap/test.py:
--------------------------------------------------------------------------------
1 | from heap import Heap
2 | from heapmodificabile import HeapModificabile
3 |
4 | class Pair:
5 | def __init__(self, x, p):
6 | self.x = x
7 | self.p = p
8 |
9 | def __lt__(self, other):
10 | return self.p< other.p
11 |
12 | def __eq__(self, other):
13 | return self.x == other.x
14 |
15 | def __hash__(self):
16 | return self.x
17 |
18 | def print(self):
19 | print("("+str(self.x)+", "+str(self.p)+")")
20 |
21 | def __str__(self):
22 | return "("+str(self.x)+", "+str(self.p)+")"
23 |
24 | def __repr__(self):
25 | return "(" + str(self.x) + ", " + str(self.p) + ")"
26 |
27 | h = HeapModificabile(10)
28 | h.ins(Pair(0,5))
29 | h.ins(Pair(1,9))
30 | h.ins(Pair(2,3))
31 | h.ins(Pair(3,6))
32 | h.ins(Pair(4,4))
33 | h.print()
34 |
35 | print(h.top())
36 | print(h.out())
37 | h.print()
38 |
39 | h.update(Pair(4,2))
40 | h.print()
41 | h.update(Pair(1,1))
42 | h.print()
43 |
44 | h.update(Pair(1,9))
45 | h.print()
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | for i in range(0,99):
2 | if i%2==1 and i%3==2 and i%4==3 and i%5==4 and i%6==5:
3 | print(i)
--------------------------------------------------------------------------------
/programmazionedinamica/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/programmazionedinamica/__init__.py
--------------------------------------------------------------------------------
/programmazionedinamica/editdistance.py:
--------------------------------------------------------------------------------
1 | # A Dynamic Programming based Python program for edit
2 | # distance problem
3 |
4 |
5 | def editdistance(str1, str2, m, n):
6 | # Create a table to store results of subproblems
7 | dp = [[0 for x in range(n + 1)] for x in range(m + 1)]
8 |
9 | # Fill d[][] in bottom up manner
10 | for i in range(m + 1):
11 | for j in range(n + 1):
12 |
13 | # If first string is empty, only option is to
14 | # insert all characters of second string
15 | if i == 0:
16 | dp[i][j] = j # Min. operations = j
17 |
18 | # If second string is empty, only option is to
19 | # remove all characters of second string
20 | elif j == 0:
21 | dp[i][j] = i # Min. operations = i
22 |
23 | # If last characters are same, ignore last char
24 | # and recur for remaining string
25 | elif str1[i - 1] == str2[j - 1]:
26 | dp[i][j] = dp[i - 1][j - 1]
27 |
28 | # If last character are different, consider all
29 | # possibilities and find minimum
30 | else:
31 | dp[i][j] = 1 + min(dp[i][j - 1], # Insert
32 | dp[i - 1][j], # Remove
33 | dp[i - 1][j - 1]) # Replace
34 |
35 | return dp[m][n]
36 |
37 |
38 | # Driver code
39 | str1 = "sunday"
40 | str2 = "saturday"
41 |
42 | print(editdistance(str1, str2, len(str1), len(str2)))
43 | # This code is contributed by Bhavya Jain
44 |
--------------------------------------------------------------------------------
/programmazionedinamica/knapsack01.py:
--------------------------------------------------------------------------------
1 | # A Dynamic Programming based Python
2 | # Program for 0-1 Knapsack problem
3 | # Returns the maximum value that can
4 | # be put in a knapsack of capacity W
5 |
6 |
7 | def knapsack(W, wt, val, n):
8 | K = [[0 for x in range(W + 1)] for x in range(n + 1)]
9 |
10 | # Build table K[][] in bottom up manner
11 | for i in range(n + 1):
12 | for w in range(W + 1):
13 | if i == 0 or w == 0:
14 | K[i][w] = 0
15 | elif wt[i-1] <= w:
16 | K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]], K[i-1][w])
17 | else:
18 | K[i][w] = K[i-1][w]
19 | return K[n][W]
20 |
21 |
22 | # Driver code
23 | val = [60, 100, 120]
24 | wt = [10, 20, 30]
25 | W = 50
26 | n = len(val)
27 | print(knapsack(W, wt, val, n))
28 |
29 | # This code is contributed by Bhavya Jain
30 |
--------------------------------------------------------------------------------
/programmazionedinamica/lcs.py:
--------------------------------------------------------------------------------
1 | # Dynamic Programming implementation of LCS problem
2 |
3 | def lcs(X, Y):
4 | # find the length of the strings
5 | m = len(X)
6 | n = len(Y)
7 |
8 | # declaring the array for storing the dp values
9 | L = [[None] * (n + 1) for i in range(m + 1)]
10 |
11 | # Following steps build L[m+1][n+1] in bottom up fashion
12 | # Note: L[i][j] contains length of LCS of X[0..i-1]
13 | # and Y[0..j-1]
14 | for i in range(m + 1):
15 | for j in range(n + 1):
16 | if i == 0 or j == 0:
17 | L[i][j] = 0
18 | elif X[i - 1] == Y[j - 1]:
19 | L[i][j] = L[i - 1][j - 1] + 1
20 | else:
21 | L[i][j] = max(L[i - 1][j], L[i][j - 1])
22 |
23 | # L[m][n] contains the length of LCS of X[0..n-1] & Y[0..m-1]
24 | return L[m][n]
25 |
26 |
27 | # end of function lcs
28 |
29 |
30 | # Driver program to test the above function
31 | X = "AGGTAB"
32 | Y = "GXTXAYB"
33 | print("Length of LCS is ", lcs(X, Y))
34 |
--------------------------------------------------------------------------------
/semplici/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sflesca/EsempiAlgoritmiPython/780dd2e398382bd42eb1c0ea081964a7aef0a259/semplici/__init__.py
--------------------------------------------------------------------------------
/semplici/codeprioritafissata.py:
--------------------------------------------------------------------------------
1 | class CodaPFIX:
2 | def __init__(self, maxp: int):
3 | self.code: list = [[] for x in range(maxp)]
4 | self.maxp: int = maxp
5 | self.size: int = 0
6 |
7 | def insert(self, val, p: int):
8 | if p < self.maxp:
9 | self.code[p].append(val)
10 | self.size += 1
11 |
12 | def pop(self):
13 | if self.size == 0:
14 | return None
15 | for i in range(maxp):
16 | if len(self.code[i]) > 0:
17 | self.size -= 1
18 | return self.code[i].pop(0)
19 |
20 | def top(self):
21 | if self.size == 0:
22 | return None
23 | for i in range(maxp):
24 | if len(self.code[i]) > 0:
25 | return self.code[i][0]
26 |
--------------------------------------------------------------------------------
/semplici/mergesort.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 |
3 |
4 | def merge_sort(arr: List[int]) -> List[int]:
5 | if len(arr) > 1:
6 | mid = len(arr) // 2 # Trova il punto medio dell'array
7 | left_half: List[int] = arr[:mid] # Dividi la parte sinistra
8 | right_half: List[int] = arr[mid:] # Dividi la parte destra
9 |
10 | merge_sort(left_half) # Ricorsivamente ordina la parte sinistra
11 | merge_sort(right_half) # Ricorsivamente ordina la parte destra
12 |
13 | merge(arr, left_half, right_half)
14 |
15 | return arr
16 |
17 |
18 | def merge(arr: List[int], left_half: List[int], right_half: List[int]) -> None:
19 | i = j = k = 0
20 |
21 | # Unisci le due metà ordinate
22 | while i < len(left_half) and j < len(right_half):
23 | if left_half[i] < right_half[j]:
24 | arr[k] = left_half[i]
25 | i += 1
26 | else:
27 | arr[k] = right_half[j]
28 | j += 1
29 | k += 1
30 |
31 | # Controlla se ci sono elementi rimasti
32 | while i < len(left_half):
33 | arr[k] = left_half[i]
34 | i += 1
35 | k += 1
36 |
37 | while j < len(right_half):
38 | arr[k] = right_half[j]
39 | j += 1
40 | k += 1
41 |
42 |
43 | # Esempio di utilizzo
44 | arr = [38, 27, 43, 3, 9, 82, 10]
45 | print("Array originale:", arr)
46 | print("Array ordinato:", merge_sort(arr))
--------------------------------------------------------------------------------
/semplici/quicksort.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import random
3 |
4 | def quick_sort(arr: List[int]) -> List[int]:
5 | if len(arr) <= 1:
6 | return arr
7 | else:
8 | pivot = random.choice(arr) # Scelta randomizzata del pivot
9 | left = [x for x in arr if x < pivot]
10 | middle = [x for x in arr if x == pivot]
11 | right = [x for x in arr if x > pivot]
12 | return quick_sort(left) + middle + quick_sort(right)
13 |
14 | # Esempio di utilizzo
15 | arr = [38, 27, 43, 3, 9, 82, 10]
16 | print("Array originale:", arr)
17 | print("Array ordinato:", quick_sort(arr))
--------------------------------------------------------------------------------
/semplici/simple.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 |
4 | def sommamatrici(a, b):
5 | c = np.zeros(a.shape)
6 | for i in range(c.shape[0]):
7 | for j in range(c.shape[1]):
8 | c[i][j] = a[i][j] + b[i][j]
9 | return c
10 |
11 |
12 | def moltiplicazionematrici(a, b):
13 | c = np.zeros((a.shape[0], b.shape[1]))
14 | for i in range(len(c)):
15 | for j in range(len(c[i])):
16 | for k in range(len(a[i])):
17 | c[i][j] += a[i][k] * b[k][j]
18 | return c
19 |
20 |
21 | def fatt(n):
22 | if n > 1:
23 | return fatt(n - 1) * n
24 | else:
25 | return 1
26 |
27 |
28 | def fatit(n):
29 | ft = 1
30 | for i in range(1, n + 1):
31 | ft *= i
32 | return ft
33 |
34 |
35 | def fib(n):
36 | if n <= 2:
37 | return 1
38 | else:
39 | return
40 |
41 |
42 | def fibc(n):
43 | if n <= 1:
44 | return 1, 1
45 | else:
46 | x, y = fibc(n - 1)
47 | return x + y, x
48 |
49 | def fib1(n):
50 | x, y = fibc(n)
51 | return x
52 |
53 |
54 | def search(vett, x):
55 | for v in vett:
56 | if v == x:
57 | return True
58 | return False
59 |
60 |
61 | def somma(vett):
62 | x = 0
63 | for v in vett:
64 | x += v
65 | return x
66 |
67 |
68 | def sommainefficiente(vett):
69 | x = [0 for i in range(len(vett) + 1)]
70 | for i in range(len(vett)):
71 | x[i + 1] = vett[i] + x[i]
72 | return x[len(vett)]
73 |
74 |
75 | def ordinamentoABolle(vett):
76 | for i in range(len(vett) - 1):
77 | scambiati = False
78 | for j in range(1, len(vett) - i):
79 | if vett[j - 1] > vett[j]:
80 | tmp = vett[j - 1]
81 | vett[j - 1] = vett[j]
82 | vett[j] = tmp
83 | scambiati = True
84 | if not scambiati:
85 | return 0
86 | return 1
87 |
88 |
89 | def merge(A, B):
90 | n = len(A)
91 | m = len(B)
92 | C = []
93 | i = 0
94 | j = 0
95 | while i < n and j < m:
96 | if A[i] <= B[j]:
97 | C.append(A[i])
98 | i = i + 1
99 | else:
100 | C.append(B[j])
101 | j = j + 1
102 | while i < n:
103 | C.append(A[i])
104 | i = i + 1
105 | while j < m:
106 | C.append(B[j])
107 | j = j + 1
108 | return C
109 |
110 |
111 | def quasifib(n):
112 | if n <= 2:
113 | return 1
114 | else:
115 | return quasifib(n - 1) + quasifib(n - 1)
116 |
--------------------------------------------------------------------------------
/semplici/test.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import time
3 |
4 | from semplici.simple import moltiplicazionematrici, sommamatrici, fatt, fatit, search, somma, sommainefficiente, \
5 | ordinamentoABolle, merge, fib, quasifib
6 |
7 | # m1 = np.array([[0, 1], [2, 3]])
8 | # m2 = np.array([[0, 2, 3], [1, 4, 5]])
9 | # m3 = sommamatrici(m1,m2)
10 | # print(m3)
11 | # m3 = moltiplicazionematrici(m1,m2)
12 | # print(m3)
13 | #
14 | # print("fatt(6)=" + str(fatt(6)))
15 | # print("fatt(6)=" + str(fatit(6)))
16 | #
17 | # trovato = search([1,2,3,4,8,5], 14)
18 | # print(trovato)
19 |
20 |
21 | v1 = np.random.randint(0, 9, 100000000)
22 | x = 15
23 | ts = time.time()
24 | trovato = search(v1, x)
25 | te = time.time() - ts
26 | if trovato:
27 | print(str(x)+" è presente")
28 | else:
29 | print(str(x) + " non è presente")
30 | print("Tempo ricerca = " + str(te)+" secondi")
31 |
32 |
33 | # v1 = np.random.randint(0, 4, 100000000)
34 | # ts = time.time()
35 | # s = somma(v1)
36 | # te = time.time() - ts
37 | # print(str(s)+"è la somma")
38 | # print("Tempo ricerca = " + str(te)+" secondi")
39 |
40 | # v1 = [1, 2,3, 6, 28, 2]
41 | # print(somma(v1))
42 | # print(sommainefficiente(v1))
43 |
44 | # v = [0,3,12,24,1,2]
45 | # v1 = [12,5, 17, 34,1]
46 | # ordinamentoABolle(v)
47 | # ordinamentoABolle(v1)
48 | # print(v)
49 | # print(v1)
50 | # v2 = merge(v,v1)
51 | # print(v2)
52 |
53 | # for i in range(1,21):
54 | # print("fib "+str(i)+"="+str(fib(i)))
55 |
56 | print(quasifib(3))
--------------------------------------------------------------------------------