Ce texte et la simulation qui l'illustre (programme complex6.bas en qbasic, par J.-P. Vanbremeersch) ont été faits en 1997 en vue de donner, sur un exemple simple, une introduction à nos SEM. Ils n'ont pas encore été publiés mais devraient figurer dans le livre sur les SEM en cours de rédaction.

1. Réseau de communication

On va modéliser le réseau des transports d'un pays.

1.1. Caractéristiques du réseau

Il est formé de différentes lignes régulières de transport reliant une localité (ville ou commune) du pays à une autre. Certaines localités ne sont reliées pas entre elles ; si une localité N est reliée à une autre N', ce peut être par une ou plusieurs lignes régulières (le sens est toujours précisé).

Le coût d'un transport est indépendant du trajet emprunté entre son point de départ N et son point d'arrivée N', mais il dépend du mode de transport et de ses caractéristiques (exemple : auto, autocar ou train, durée du parcours, confort, fréquence, nombre de voyageurs…) ; ceci est évalué en attribuant à chaque transport g une "cote" de confort ou commodité (représentée par un entier p(g)). Par exemple un billet de 1e classe aura une cote plus grande qu'un billet de 2e classe. Ainsi un transport est-il caractérisée par la localité de départ, la localité d'arrivée et sa cote.

Si g est une ligne de N vers N' et si g' est une ligne de N' à N", le réseau permet aussi d'aller de N à N" en empruntant d'abord g puis g' ; si g et g' n'ont pas la même cote, la cote attribuée à cette ligne "composée" g.g' de N vers N" sera la plus grande de leurs deux cotes (si le voyage se fait en 1e classe sur une partie du trajet, on doit payer le prix de la 1e classe sur le parcours total même si on voyage en 2e sur une autre partie). En formule :

p(g.g') = max(p(g), p(g')).

1.2. Réseau régional, réseaux ciblés

Le pays est divisé en régions et chaque région P gère son propre réseau régional de transports; c'est un sous-réseau du réseau global formé de lignes reliant diverses localités de la région. En général elle ne gère pas les lignes la reliant à des localités extérieures à la région. Toutefois il peut exister une localité C dans laquelle un certain nombre d'habitants de la région doivent se rendre régulièrement. Penser par exemple aux étudiants d'une région sans université qui vont suivre les cours de l'université la plus proche ; ou à des envois de marchandises vers un centre commercial plus important.

Dans ce cas pour bénéficier d'un meilleur service (lignes plus fréquentes, tarifs plus avantageux), la région peut exploiter, à l'intérieur du réseau global, un réseau ciblé vers C, coordonné à son réseau régional. Dans un tel réseau ciblé, chacune des localités Pi de la région est reliée à C par une ligne particulière (dite "ciblée") qi gérée par la région, choisie de sorte que la contrainte suivante soit vérifiée : un habitant de Pi peut choisir, pour le même prix, d'aller à C soit directement par qi, soit indirectement en empruntant d'abord une ligne régionale f de Pi vers un Pj puis la ligne ciblée qj de Pj vers C ; ce qui signifie que les cotes de qi et de la ligne composée f.qj doivent avoir les mêmes. Autrement dit, les qi sont tels que la cote p(qi) est la plus grande des cotes de f et de qj, pour toute ligne régionale f de Pi vers Pj.

1.3. Nœud central

Si la région P a des réseaux ciblés vers différentes villes extérieures, l'administration en sera simplifiée s'il existe un nœud central de communication par lequel ses différents réseaux ciblés transitent. Un tel nœud sera une localité L, généralement extérieure à la région, dont l'emplacement est choisi de sorte que les conditions suivantes soient vérifiées :

Le nœud central permet par exemple d'organiser des voyages groupés vers n'importe laquelle des localités C : les membres du groupe habitant Pi iront individuellement à L (via les lignes ciblées li), puis feront tous ensemble le voyage de L vers C. Il permet aussi à des gens extérieurs à la région et qui devraient se rendre à C en passant par la région de la contourner sans y pénétrer (en particulier pour éviter le traffic interne) : ils vont directement à L puis empruntent la ligne q de L vers C.

Si aucune des localités auxquelles P est reliée dans le réseau global ne peut jouer le rôle de ce nœud central, la région pourra chercher à créer un tel nœud en un endroit adéquat, en étendant le réseau global par l'organisation des nouveaux transports requis pour cela. Toutefois cette opération n'est pas toujours possible, du moins si l'on tient à respecter strictement les conditions de cotes.

1.4. Réseau inter-régional

Jusqu'ici nous n'avons parlé que d'une région P. Nous allons maintenant étudier les transports entre deux régions ; différentes localités de P peuvent être reliées à des localités d'une autre région R par des lignes du réseau global. Mais pour augmenter leurs échanges, deux régions P et R peuvent se concerter pour exploiter en commun un sous-réseau du réseau global et en faire un véritable réseau inter-régional de P vers R, coordonné avec les réseaux régionaux de P et de R. Les propriétés requises d'un tel réseau inter-régional U sont les suivantes :

Dans ce cas, si la région R a un nœud central M et P un nœud central L, le réseau inter-régional U "s'intègre" en une ligne û de L vers M. En effet, dans ce cas les lignes composées d'un u et de la ligne ciblée de Rk vers M, forment un réseau ciblé de P vers M, et û est la ligne centrale de L vers M attachée à ce réseau. Ainsi pour aller de Pi à M un voyageur peut traverser R ou aller directement de L vers M : il revient au même d'aller de Pi à L par la ligne ciblée li puis de L à M par û, ou d'aller de Pi à Rk par u puis de Rk à M par mk.

1.5. Transports entre nœuds centraux

Si l'on a des réseaux inter-régionaux de Q vers P et de P vers R, les transports obtenus en composant leurs lignes forment un réseau inter-régional de Q vers R, qui s'intègre donc en un transport du nœud central de Q vers celui de R.

Mais les nœuds centraux de deux régions peuvent être reliés sans qu'il y ait de réseau inter-régional entre elles. Un cas extrême est celui de deux régions P et P' qui ont le même nœud central L sans avoir de réseau inter-régional ; ceci est possible si les deux régions ont des réseaux ciblés vers les mêmes localités.

Dans ce cas, si U' est un réseau inter-régional d'une région R' vers P' et U un réseau inter-régional de P vers R, les nœuds centraux M' de R' et M de R sont reliés par la ligne composée û'.û ; et pourtant R' et R n'ont pas nécessairement de réseau inter-régional. Cette ligne permet de transiter par L sans pénétrer dans la région P ou P'.

Remarque. Dans l'exemple précédent, on pourrait remplacer la cote de confort par un seuil de rentabilité (représentant le nombre minimum de voyageurs couvrant les frais d'exploitation).

1.6. Modélisation du réseau

Le réseau global est modélisé par une catégorie K : Ses objets représentent les différentes localités N du réseau, une flèche de N vers N' représente une ligne du réseau, qu'on notera c: N ® N' où c est sa cote ; le composé de c: N ® N' avec c': N' ® N" est la flèche max(c,c'): N ® N" (qui représente bien la ligne composée).

Au réseau régional d'une région P est associé un pattern de K, aussi noté P. Un réseau ciblé de P vers un C est modélisé par un lien collectif de P vers C (représenté par un cône). La région a un nœud central de communication L si P admet L pour colimite dans K.

Un réseau inter-régional U de P vers une région R est modélisé par une gerbe entre les patterns qui les représentent. Si P et R ont des nœuds centraux (donc des colimites L et M), il s'intègre en un "lien simple" û de L vers M.

Si P n'a pas de colimite dans K, on cherche à en ajouter une (modélisant un nœud entral) par le processus de complexification de K relatif à la stratégie consistant à ajouter une colimite à P. Ce processus appliqué à plusieurs régions simultanément conduit à l'introduction de "liens complexes" qui sont des composés de liens simples intégrant des gerbes non adjacentes. Ils modélisent les transports que nous avons considéré au 1-5, obtenus lorsque P et P' ont le même nœud central, et que l'on a des réseaux inter-régionaux de R' vers P' et de P vers R.

Les conditions pour qu'il existe un nœud central pour une région dans le réseau initial, ou sinon pour qu'on puisse en ajouter un, vont être étudiées dans le cadre un peu plus général des catégories associées à un graphe pondéré, et illustrées par une simulation en qbasic.

En particulier il en résultera que, si une région P n'a pas de nœud central, il n'est pas toujours possible d'en ajouter un vérifiant les contraintes sur les cotes : on pourra bien ajouter un L avec un réseau ciblé (li) dont la cote de chaque Li est minimum, et une ligne centrale q de L vers chaque C pour chaque réseau ciblé (qi) de P vers C, mais la cote de ce q n'est plus déterminée en fonction des cotes des qi.

 

2. Modélisation mathématique

2.1. Catégorie associée à un graphe pondéré

Ici graphe signifiera toujours multi-graphe orienté, i.e. la donnée d'un ensemble d'objets et de flèches entre eux. Une catégorie peut être définie comme un graphe K muni d'une loi de composition interne associant à 2 flèches consécutives f: A ® B et g: B ® C une flèche f.g: A ® C, cette composition vérifiant 2 axiomes : associativité (f.g).h = f.(g.h) ; identité : pour tout objet A il existe une flèche idA: A ® A qui composée à droite ou à gauche avec une autre flèche redonne cette autre flèche.

A tout graphe G on associe une catégorie C(G), appelée catégorie des chemins de G, de la manière suivante : Elle a les mêmes objets que G et les flèches sont tous les chemins (suite de flèches consécutives) entre ses objets ; la composition interne est définie en prenant pour composé de deux chemins consécutifs (f1,...,fn) et (g1,...gm) le chemin concaténé (f1,...,fn,g1,...,gm).

Un graphe pondéré (G,p) dans un monoïde A est un graphe G muni d'une application p: G ® A associant à chaque flèche f de G un élément p(f) de A, appelé son poids. (Un monoïde est une catégorie avec un seul objet.) Ces poids sont étendus à C(G) en prenant pour poids d'un chemin le composé des poids de ses facteurs dans le monoïde A. En identifiant 2 chemins de même source et de même but lorsqu'ils ont le même poids, on obtient une catégorie quotient de C(G) qui a les mêmes objets que G, et dont les flèches sont les classes de chemins de même poids. Cette catégorie est dite associée au graphe pondéré (G,p) et on la note K(G,p).

Dans la suite, on se place dans le cas où A est le monoïde (N, max) des entiers muni de la composition max(i,j). La catégorie K(G,p) est alors obtenue à partir de la catégorie des chemins de G en y identifiant 2 chemins de même poids, le poids d'un chemin F = (f1,…,fn) étant p(F) = max(p(f1),…,p(fn)). Dans cette catégorie, étant donnés 2 objets i et j, il existe au plus une flèche de poids c de i vers j, et on peut donc la noter c: i ® j.

La catégorie associée au réseau de communication (cf. 1.6) est la catégorie associée au graphe formé par les lignes du réseau, pondéré par leurs cotes.

2.2. Existence d'une colimite

Dans une catégorie K, un pattern P est un sous-graphe de la catégorie qui modélise un ensemble d'objets avec des liens distingués entre eux. Un lien collectif de P vers un objet C est une famille de liens individuels (Qi), un pour chaque objet i de P, compatible avec tout lien distingué F de P au sens que Qi = F.Qj si F va de i vers j. On le représente par un cône de base P et de sommet C. Le pattern a une colimite L s'il existe un lien collectif (Li) de P vers L par lequel tout autre lien collectif (Qi) de P vers C se décompose d'une manière unique, c'est-à-dire tel qu' on ait un et un seul Q de L vers C vérifiant Qi = Li.Q pour tout i.

Prenons maintenant pour K la catégorie K(G,p) considérée à la fin de 2.1, et soit P un pattern dans K. Un lien collectif de P vers un objet C est alors une famille (qi: i  ® C) de flèches issues des objets de P telle que, pour tout lien distingué f: i ® j de P, on ait

qi = max(f, qj).

P admet une colimite L s'il existe un lien collectif "canonique" (lii ® L) de P vers L, et si, pour tout lien collectif (qii ® C) vers un C quelconque, il existe un et un seul lien q: L ® C vérifiant

(1) qi = max(li, q) pour tout objet i de P.

Cette condition impose des contraintes très fortes sur les cônes. En effet, on voit qu'elle est équivalente à la conjonction des 2 conditions suivantes :

(a) Il existe un cône (li: i ® L) "minimum", au sens que

li £ qi pour tout cône (qii ® C) et tout objet i de P .

(b) Pour tout autre cône (qii ® C), on a :

Remarque. Un lien collectif de P vers C détermine aussi un lien collectif du pattern P' obtenu en ajoutant à P tous les composés de ses différents liens dans la catégorie (de sorte que P' est la sous-catégorie de K engendrée par P). Ainsi P et P' ont la même colimite, si elle existe.

2.3. Complexification

Si P n'a pas de colimite dans K, le processus de "complexification" permet d'étendre de manière "minimale" K en une catégorie dans laquelle P acquiert une colimite. Deux cas sont possibles:

qi = max(qj, f)

entraînent

min{qi|q} = max(min{qj|q}, f).

Mais si un des cônes q ne vérifie pas la condition (b), on ne pourra pas mettre un poids adéquat sur la flèche le décomposant, à savoir le minimum des qi. Donnons un contr'exemple : P a une flèche 3 : i ® j et un autre objet k les autres éléments formant un cône de poids 3,3,5 vers C et un cône de poids 4,4,4 vers C'. Alors les poids des liens vers L' seront 3,3,4, mais la flèche de L' vers C décomposant le cône ne peut pas être pondérée de façon adéquate, car son poids d devrait vérifier: max(d, 3) = 4 = max(d, 5).

 

3. Simulation

La construction d'une colimite dans la catégorie K associée à un graphe (G,p) pondéré dans (N, max) est simulée dans "Complexif6.bas".

3.1. Hypothèses

Le graphe G (choisi de manière aléatoire) a 14 sommets, notés 1 à 14, dont les poids varient entre 1 et 10. La catégorie K des classes de chemins de G de même poids est construite en ajoutant à G les composés de deux flèches successives, puis en recommençant l'opération jusqu'à avoir tous les composés possibles. En notant une flèche de i vers j par f: i ® jf est son poids, son composé avec g: j ® k est max(f, g): i ® k.

Pour simplifier on suppose que G a au plus une flèche allant d'un i vers un j et qu'il n'existe pas de flèche allant d'un j > 4 vers un i < 5.

On prend pour pattern P le sous-graphe formé de toutes les flèches entre les objets 1, 2, 3, 4; ce sous-graphe est dessiné et son "tableau" est indiquée en bas à droite. On construit la sous-catégorie P' de K engendrée par P (c'est la sous-catégorie pleine de K ayant pour objets 1,2,3,4) en ajoutant à P les composés de deux flèches successives, puis en recommençant l'opération jusqu'à avoir tous les composés possibles. P' est dessinée.

3.2. Recherche des liens collectifs de P vers un objet C

Un objet C de K étant choisi, on dessine les flèches du graphe G allant d'un objet de P vers C (leur valeur est affichée en bas à droite du tableau de P). En formant tous les composés possibles de ces flèches avec celles dans P', on construit la sous-catégorie de K engendrée par P et ces flèches et C et on la dessine ; le nombre de ses flèches de i < 5 vers C est indiqué dans le tableau.

On forme toutes les suites possibles de 4 flèches (qi: i ® C), i < 5. Le nombre de ces suites est indiqué en haut à droite, suivi de la valeur de C. Pour chacune, on cherche si elle définit un lien collectif de P vers C (cône), i.e. si qi = max(qj, f) pour chaque flèche f: i ® j de P ; dans ce cas on note ce cône à côté de C en indiquant les poids de ses 4 qi.

3.3. Recherche d'une colimite

(1) max(n, li) = qi pour tout i < 5.

Si cette condition n'est pas vérifiée, il n'y a pas de colimite.

Si elle est vérifiée, L est une colimite de P à condition que pour tout cône, il existe une et une seule flèche n: L ® C dans la catégorie K dont le poids n vérifie (1).

Un dessin final affiche les différents cônes et, si elle existe, la colimite. On peut mémoriser l'exemple avec ses particularités.

Remarques. 1. A part à la fin de la vérification d'une colimite, la simulation ne tient pas compte des flèches entre objets > 5. En fait, on construit seulement (via la construction de P' puis des flèches de i < 5 vers un C pour chaque C) la sous-catégorie K' formée des flèches de source 1, 2, 3, 4 et de leurs buts. On suppose donc que G est choisi de sorte que K soit la réunion de K' avec l'ensemble des flèches entre objets > 5. Bien que le programme affiche des valeurs pour C < 4, ceci est juste pour avoir un traitement formel identique pour tous les cônes, mais ces valeurs ne sont pas utilisées et les calculs n'en tiennent pas compte ; si on en tenait compte, P' ne serait plus une sous-catégorie pleine de K car il faudrait rajouter à K leurs composés avec les flèches de P', et ces composés interviendraient dans les calculs ultérieurs, avec possibilité d'introduire de nouveaux cônes.

2. S'il n'existe pas de complexification pondérée, nous avons vu que le processus de "complexification" permet quand même de construire une catégorie dans laquelle P acquiert une colimite, mais cette catégorie n'est pas pondérée dans (N, max). Ce cas n'est pas traité dans la simulation.

3. Le programme est facilement modifé pour simuler la recherche de colimite dans le cas où le poids du composé n'est plus le maximum des poids de ses facteurs mais leur minimum, ou encore est leur somme modulo N. Le "modulo N " est introduit pour conserver un nombre fini de flèches dans la catégorie.

4. Programme

Programme écrit en 1997 par J.P. Vanbremeersch

  • DECLARE FUNCTION mini! (d1!, d2!)
  • DECLARE FUNCTION maxi (n1, n2)
  • 'KILL "temps1"
  • TYPE valeur
  • expliq AS STRING * 30
  • tps AS SINGLE
  • END TYPE
  • DIM relation AS valeur
  • SCREEN 12
  • COLOR 14
  • LOCATE 2, 10: PRINT " Voulez-vous partir d'un enregistrement O / N ?"
  • g$ = INPUT$(1)
  • IF UCASE$(g$) = "O" THEN
  • CLEAR
  • GOSUB fichierlit
  • ELSE
  • temporisation = 0
  • END IF
  • IF temporisation = 0 THEN
  • CLEAR : CLS
  • END IF
  • LOCATE 10, 16: PRINT "Pour ralentir le programme,"
  • LOCATE 12, 13: PRINT "tapez 'a', ce qui cr‚era des arrˆts"
  • LOCATE 14, 15: PRINT "sinon n'importe quelle touche."
  • LOCATE 18, 16: PRINT " Mais, en cours de programme"
  • LOCATE 20, 16: PRINT " vous pouvez supprimer ces arrˆts"
  • LOCATE 22, 16: PRINT " en tapant 's' lors d'un arrˆt."
  • k$ = INPUT$(1)
  • CLS
  • DIM rel(4, 4, 10), affich1(15), affich2(15), colF(11)
  • DIM Ki(4, 800), kCone(4, 50, 20), numC(50), pC(4, 10, 15)
  • DIM nbrepC(4, 15)
  • DIM xA(15), yA(15), xx(15), yy(15)
  • DIM dec(50, 50), yz(50)
  • LOCATE 27, 1: PRINT " Choix en cours "
  • ' GOSUB grille
  • GOSUB donnees1
  • GOSUB choix
  • GOSUB pattern
  • FOR nc = 1 TO 14
  • IF nc <= 4 THEN
  • CAN = 1
  • ELSE
  • CAN = 0
  • END IF
  • ERASE Ki
  • gh = 0
  • GOSUB dessin0
  • GOSUB choixC
  • GOSUB composition
  • GOSUB liste
  • GOSUB cones1
  • NEXT nc
  • LOCATE 26, 4: PRINT " Fin des calculs des c"nes;"
  • LOCATE 27, 4: PRINT " pour continuer et changer d'affichage "
  • LOCATE 28, 4: PRINT " tapez sur n'importe quelle touche. "
  • f$ = INPUT$(1)
  • GOSUB donnees2
  • IF cone >= 1 THEN
  • GOSUB colim
  • END IF
  • IF colimite <> 0 THEN
  • GOSUB flechescol
  • END IF
  • IF cone = 0 THEN
  • LOCATE 26, 1: PRINT " Pas de C"ne. Pas de Colimite. "
  • END IF
  • f$ = INPUT$(1)
  • IF temporisation = 0 THEN 'c...d., si ne s'agit pas d'un exemple enregistr‚
  • GOSUB fichierenregistre
  • END IF
  • END
  • flechescol:
  • FOR d = 1 TO cone
  • cp = 9: dec = 0: dec0 = 0: KOL = 1
  • IF d <> colimite THEN
  • FOR i = 1 TO 4
  • IF pC(i, kCone(i, d, numC(d)), numC(d)) = pC(i, kCone(i, colimite, numC(colimite)), numC(colimite)) THEN
  • cp = mini(cp, pC(i, kCone(i, d, numC(d)), numC(d)))
  • ELSEIF pC(i, kCone(i, d, numC(d)), numC(d)) > pC(i, kCone(i, colimite, numC(colimite)), numC(colimite)) THEN
  • dec0 = pC(i, kCone(i, d, numC(d)), numC(d))
  • IF dec = 0 THEN
  • dec = dec0
  • END IF
  • END IF
  • IF dec0 <> dec OR dec > cp THEN
  • KOL = 0
  • END IF
  • NEXT i
  • END IF
  • IF KOL = 1 THEN
  • dec(colimite, d) = dec
  • IF dec = 0 THEN
  • dec(d, colimite) = 0
  • col = 15
  • ELSE
  • col = colF(dec(colimite, d))
  • END IF
  • COLOR col
  • LOCATE yz(d), 77: PRINT dec(colimite, d)
  • IF numC(d) = numC(d + 1) AND d < cone THEN
  • haut = haut + 3
  • ELSE
  • haut = 0
  • END IF
  • LINE (xA(numC(colimite)), yA(numC(colimite)))-(xA(numC(d)), yA(numC(d)) + haut), col
  • COLOR 15
  • LOCATE yz(colimite), 77: PRINT "Cmin"
  • ELSE
  • LOCATE 28, 1: PRINT " Pas de COMPLEX "
  • pascomplex = 1
  • END IF
  • NEXT d
  • RETURN
  • liste:
  • ' top
  • r = 1
  • FOR l = 1 TO nbrepC(1, nc)
  • FOR m = 1 TO nbrepC(2, nc)
  • FOR n = 1 TO nbrepC(3, nc)
  • FOR o = 1 TO nbrepC(4, nc)
  • Ki(1, r) = l
  • Ki(2, r) = m
  • Ki(3, r) = n
  • Ki(4, r) = o
  • ' LOCATE r, 1: PRINT Ki(1, r), Ki(2, r), Ki(3, r), Ki(4, r)
  • r = r + 1
  • NEXT o, n, m, l
  • ycone = ycone + 1
  • IF nc > 4 THEN
  • COLOR 15
  • ELSE
  • COLOR col(nc)
  • END IF
  • LOCATE ycone, 56: PRINT r
  • LOCATE ycone, 60: PRINT "C"; nc
  • COLOR 15
  • RETURN
  • cones1:
  • non = 0
  • FOR liste = 1 TO r
  • LOCATE 27, 1: PRINT " Calculs c"nes en cours "
  • oui = 1
  • FOR i = 1 TO 4
  • FOR j = 1 TO 4
  • FOR h1 = 1 TO nbre(i, j)
  • IF maxi(rel(i, j, h1), pC(j, Ki(j, liste), nc)) <> pC(i, Ki(i, liste), nc) THEN
  • oui = 0
  • END IF
  • NEXT h1
  • NEXT j
  • NEXT i
  • IF oui = 1 THEN
  • gh = gh + 1
  • cone = cone + 1
  • numC(cone) = nc
  • kCone(1, cone, nc) = Ki(1, liste)
  • kCone(2, cone, nc) = Ki(2, liste)
  • kCone(3, cone, nc) = Ki(3, liste)
  • kCone(4, cone, nc) = Ki(4, liste)
  • GOSUB affichcone
  • END IF
  • NEXT liste
  • LOCATE 27, 1: PRINT " Calculs c"nes effectu‚s"
  • GOSUB texte
  • RETURN
  • 'top
  • conemini:
  • cone = cone + 1
  • colimite = cone
  • yz(cone) = 23
  • CIRCLE (xA(15), yA(15)), 15, 2: PAINT (xA(15), yA(15) - 6), 15, 2
  • LOCATE 1, xx(15) + 5: PRINT "C 15 mini"; STR$(min(1)); STR$(min(2)); STR$(min(3)); STR$(min(4))
  • numC(colimite) = 15
  • FOR i = 1 TO 4
  • pC(i, kCone(i, 15, numC(colimite)), numC(colimite)) = min(i)
  • LINE (xP(i), yP(i))-(xA(15), yA(15)), 15
  • NEXT i
  • GOSUB flechescol
  • RETURN
  • colim:
  • FOR i = 1 TO 4
  • min(i) = pC(i, kCone(i, 1, numC(1)), numC(1))
  • NEXT i
  • FOR d = 2 TO cone
  • FOR i = 1 TO 4
  • IF pC(i, kCone(i, d, numC(d)), numC(d)) < min(i) THEN
  • min(i) = pC(i, kCone(i, d, numC(d)), numC(d))
  • END IF
  • NEXT i
  • NEXT d
  • FOR d = 1 TO cone
  • co = 0
  • FOR i = 1 TO 4
  • IF pC(i, kCone(i, d, numC(d)), numC(d)) = min(i) THEN
  • co = co + 1
  • END IF
  • NEXT i
  • IF co = 4 THEN
  • colimite = d
  • ELSE
  • co = 0
  • END IF
  • NEXT d
  • IF colimite <> 0 THEN
  • LOCATE 28, 1: PRINT " COLIMITE = c"ne "; colimite
  • ELSE
  • LOCATE 28, 1: PRINT " Pas de COLIMITE "
  • GOSUB conemini
  • END IF
  • GOSUB affichcolimite
  • RETURN
  • composition:
  • LOCATE 27, 1: PRINT " Calculs composition en cours "
  • DO
  • tour = 0
  • FOR i = 1 TO 4
  • IF nbrepC(i, nc) <> 10 THEN
  • FOR j = 1 TO 4
  • FOR k = 1 TO nbre(i, j)
  • non = 0
  • IF i <> j AND rel(i, j, k) <> 0 THEN
  • FOR hh = 1 TO nbrepC(j, nc)
  • FOR h = 1 TO nbrepC(i, nc)
  • IF maxi(rel(i, j, k), pC(j, hh, nc)) = pC(i, h, nc) THEN
  • non = 1
  • END IF
  • NEXT h
  • IF non = 1 THEN EXIT FOR
  • IF non = 0 AND CAN = 0 THEN
  • nbrepC(i, nc) = nbrepC(i, nc) + 1
  • pC(i, nbrepC(i, nc), nc) = maxi(rel(i, j, k), pC(j, hh, nc))
  • tour = 1
  • GOSUB affichC
  • END IF
  • IF non = 0 AND CAN = 1 AND i <> nc THEN
  • nbrepC(i, nc) = nbrepC(i, nc) + 1
  • pC(i, nbrepC(i, nc), nc) = maxi(rel(i, j, k), pC(j, hh, nc))
  • tour = 1
  • GOSUB affichC
  • END IF
  • NEXT hh
  • END IF
  • NEXT k
  • NEXT j
  • END IF
  • NEXT i
  • LOOP UNTIL tour = 0
  • LOCATE 27, 1: PRINT " Calculs composition effectu‚s"
  • GOSUB texte
  • RETURN
  • pattern:
  • LOCATE 27, 1: PRINT " Calculs pattern en cours "
  • DO
  • calc = 0
  • FOR i1 = 1 TO 4
  • FOR j1 = 1 TO 4
  • FOR h1 = 1 TO nbre(i1, j1)
  • FOR k1 = 1 TO 4
  • IF nbre(i1, k1) <> 10 THEN
  • FOR h2 = 1 TO nbre(j1, k1)
  • non = 0
  • P = maxi(rel(i1, j1, h1), rel(j1, k1, h2))
  • FOR s = 1 TO nbre(i1, k1)
  • IF rel(i1, k1, s) = P THEN
  • non = 1
  • END IF
  • NEXT s
  • IF non = 1 THEN EXIT FOR
  • IF non = 0 THEN
  • 'c = c + 1
  • 'LOCATE 1, 1: PRINT c
  • nbre(i1, k1) = nbre(i1, k1) + 1
  • rel(i1, k1, s) = P
  • kk = s
  • i = i1: j = k1
  • calc = 1
  • GOSUB affichIJ
  • END IF
  • NEXT h2
  • END IF
  • NEXT k1
  • NEXT h1
  • NEXT j1
  • NEXT i1
  • LOOP UNTIL calc = 0
  • LOCATE 27, 1: PRINT " Calculs pattern effectu‚s"
  • GOSUB texte
  • RETURN
  • choix:
  • choix = 0
  • IF temporisation = 0 THEN
  • temps = TIMER
  • END IF
  • RANDOMIZE temps
  • LOCATE 1, 10: PRINT "RANDOM ="; temps
  • ERASE rel
  • FOR i = 1 TO 4
  • FOR j = 1 TO 4
  • rel = INT(RND * 2)
  • kk = 0
  • IF i <> j AND rel <> 0 AND rel(j, i, 1) = 0 THEN
  • rel = INT(RND * 10)
  • rel(i, j, 1) = rel
  • rel1(i, j, 1) = rel
  • IF rel <> 0 THEN
  • nbre1(i, j) = nbre1(i, j) + 1
  • nbre(i, j) = nbre(i, j) + 1
  • END IF
  • kk = 1
  • END IF
  • GOSUB affichIJ
  • i1 = i: j1 = j
  • NEXT j
  • NEXT i
  • FOR i = 1 TO 4
  • LOCATE y(i), x(i): PRINT i
  • NEXT i
  • choix = 1
  • LOCATE 27, 1: PRINT " Choix initial effectu‚"
  • GOSUB texte
  • RETURN
  • choixC:
  • choixC = 0
  • suiteC = 0
  • FOR i = 1 TO 4
  • rel = INT(RND * 10)
  • pC(i, 1, nc) = rel
  • IF rel <> 0 THEN
  • nbrepC(i, nc) = 1
  • END IF
  • IF CAN = 1 AND i = nc THEN
  • pC(i, 1, nc) = 0
  • END IF
  • GOSUB affichC
  • NEXT i
  • LOCATE 27, 1: PRINT " Choix C effectu‚."
  • GOSUB texte
  • choix = 1
  • choixC = 1
  • suite = 3
  • suiteC = 3
  • RETURN
  • affichcone:
  • IF nc > 4 THEN
  • col = 1
  • ELSE
  • col = col(nc)
  • END IF
  • LOCATE yy(nc), xx(nc): PRINT nc
  • CIRCLE (xA(nc), yA(nc)), 15, 15: PAINT (xA(nc), yA(nc) - 6), col, 15
  • IF nc > 4 THEN
  • COLOR 15
  • ELSE
  • COLOR col(nc)
  • END IF
  • IF gh > 1 THEN
  • ycone = ycone + 1
  • END IF
  • yz(cone) = ycone
  • LOCATE ycone, 65: PRINT "/c"";
  • LOCATE ycone, 68: PRINT RIGHT$(STR$(cone), 2)
  • LOCATE ycone, 71: PRINT RIGHT$(STR$(pC(1, kCone(1, cone, nc), nc)), 1)
  • LOCATE ycone, 72: PRINT RIGHT$(STR$(pC(2, kCone(2, cone, nc), nc)), 1)
  • LOCATE ycone, 73: PRINT RIGHT$(STR$(pC(3, kCone(3, cone, nc), nc)), 1)
  • LOCATE ycone, 74: PRINT RIGHT$(STR$(pC(4, kCone(4, cone, nc), nc)), 1)
  • COLOR 15
  • RETURN
  • affichcolimite:
  • IF colimite <> 0 AND pascomplex = 0 THEN
  • col = 15
  • nc = numC(colimite)
  • CIRCLE (210, 350), 90, 0, , , .75
  • LINE (xP(1) - 10, yP(1) + 10)-(xA(nc), yA(nc)), col: LINE -(xP(3) + 10, yP(1) + 10), col: LINE -(xP(1) - 10, yP(1) + 10), col
  • PAINT (xP(1) + 20, yP(1) - 2), 15, 15
  • END IF
  • FOR i = 1 TO 4
  • FOR d = 1 TO cone
  • IF d <> colimite THEN
  • col = colF(pC(i, kCone(i, d, numC(d)), numC(d)))
  • LINE (xP(i), yP(i))-(xA(numC(d)), yA(numC(d))), col
  • END IF
  • NEXT d, i
  • FOR i = 1 TO 14
  • IF i > 4 THEN
  • col = 1
  • ELSE
  • col = col(i)
  • END IF
  • LOCATE yy(i), xx(i): PRINT i
  • CIRCLE (xA(i), yA(i)), 15, 15: PAINT (xA(i), yA(i) - 6), col, 15
  • NEXT i
  • GOSUB dessin01
  • RETURN
  • affichIJ:
  • x = 0: y = 0
  • IF nbre(i, j) <> 1 THEN
  • x = xvar(i, j) * nbre(i, j): y = yvar(i, j) * nbre(i, j)
  • END IF
  • IF choix = 0 THEN
  • IF kk <> 0 THEN
  • COLOR colF(rel(i, j, kk))
  • LOCATE i + 24, j * 3 + 45: PRINT rel(i, j, kk)
  • COLOR 15
  • END IF
  • END IF
  • IF rel(i, j, kk) = 0 THEN
  • col = 0
  • ELSE
  • col = colF(rel(i, j, kk))
  • END IF
  • LINE (xP(i), yP(i))-(xP(i) + affich3(i, j) + x, yP(i) + affich4(i, j) + y), col: LINE -(xP(j), yP(j)), col
  • LINE (xP(i) + affich3(i, j) + fche1(i, j) + x, yP(i) + affich4(i, j) + fche2(i, j) + y)-(xP(i) + affich3(i, j) + x, yP(i) + affich4(i, j) + y), col
  • LINE (xP(i) + affich3(i, j) + fche3(i, j) + x, yP(i) + affich4(i, j) + fche4(i, j) + y)-(xP(i) + affich3(i, j) + x, yP(i) + affich4(i, j) + y), col
  • RETURN
  • affichC:
  • IF suiteC = 0 THEN
  • LOCATE i + 24, 70 + 3: PRINT " "
  • END IF
  • LOCATE i + 24, 65: PRINT i; "C "
  • LOCATE i + 24, 70 + suiteC: PRINT nbrepC(i, nc)
  • n = nbrepC(i, nc)
  • col = colF(pC(i, n, nc))
  • IF choixC = 0 THEN
  • COLOR col
  • LOCATE i + 24, 58 + 3: PRINT pC(i, n, nc)
  • COLOR 15
  • END IF
  • LINE (xP(i), yP(i))-(xP(i) + affich1(n), yP(i) + affich2(n)), col: LINE -(xA(nc), yA(nc)), col
  • LINE (xP(i) + affich1(n) - 5, yP(i) + affich2(n) + 5)-(xP(i) + affich1(n), yP(i) + affich2(n)), col
  • LINE (xP(i) + affich1(n) + 5, yP(i) + affich2(n) + 5)-(xP(i) + affich1(n), yP(i) + affich2(n)), col
  • IF nc > 4 THEN
  • col = 1
  • ELSE
  • col = col(nc)
  • END IF
  • LOCATE yy(nc), xx(nc): PRINT nc
  • CIRCLE (xA(nc), yA(nc)), 15, 2: PAINT (xA(nc), yA(nc) - 6), col, 2
  • RETURN
  • dessin01:
  • CIRCLE (210, 350), 90, 3, , , .75: PAINT (210, 350), 0, 3: CIRCLE (210, 350), 90, 15, , , .75
  • FOR i = 1 TO 4
  • FOR j = 1 TO 4
  • IF rel1(i, j, 1) <> 0 THEN
  • col = colF(rel(i, j, 1))
  • LINE (xP(i), yP(i))-(xP(i) + affich3(i, j), yP(i) + affich4(i, j)), col: LINE -(xP(j), yP(j)), col
  • LINE (xP(i) + affich3(i, j) + fche1(i, j), yP(i) + affich4(i, j) + fche2(i, j))-(xP(i) + affich3(i, j), yP(i) + affich4(i, j)), col
  • LINE (xP(i) + affich3(i, j) + fche3(i, j), yP(i) + affich4(i, j) + fche4(i, j))-(xP(i) + affich3(i, j), yP(i) + affich4(i, j)), col
  • END IF
  • NEXT j
  • CIRCLE (xP(i), yP(i)), 15, col(i): PAINT (xP(i), yP(i) + 1), col(i), col(i)
  • LOCATE y(i), x(i): PRINT i
  • NEXT i
  • RETURN
  • donnees1:
  • DATA 4,5,6,9,10,11,12,13,14
  • FOR i = 1 TO 9
  • READ colF(i)
  • LINE (10, i * 16 + 10)-(30, i * 16 + 8), colF(i), BF
  • COLOR colF(i)
  • LOCATE i + 1, 1: PRINT i
  • NEXT i
  • COLOR 15
  • FOR i = 1 TO 4
  • COLOR 14
  • LOCATE 22, 49: PRINT "Choix init."
  • LOCATE i + 24, 44: PRINT i
  • LOCATE 23, i * 3 + 45: PRINT i
  • NEXT i
  • LINE (350, 380)-(370, 360): LINE (370, 360)-(365, 370): LINE (370, 360)-(360, 365)
  • COLOR 9: LOCATE 23, 61: PRINT " C"
  • COLOR 15
  • DATA 0,-3,0,-3,-2,-2,0,3,-2,-2,2,-2,0,3,-2,-2,-2,-3,2,2,2,-2,-1,3
  • FOR i = 1 TO 4
  • FOR j = 1 TO 4
  • IF i <> j THEN
  • READ xvar(i, j), yvar(i, j)
  • END IF
  • NEXT j
  • NEXT i
  • DATA 130,15,160,-30,60,-60
  • DATA -130,30,50,0,-40,-50
  • DATA -160,30,-35,20,-120,-50
  • DATA -60,60,50,50,80,10
  • FOR i = 1 TO 4
  • FOR j = 1 TO 4
  • IF i <> j THEN
  • READ affich3(i, j), affich4(i, j)
  • END IF
  • NEXT j
  • NEXT i
  • DATA -5,-5,-5,5,-5,-5,-5,5,-6,-1,0,6
  • DATA 5,-5,5,5,-6,-5,-5,5,8,3,0,8
  • DATA 5,-5,5,5,6,-1,0,-6,7,-3,4,7
  • DATA 6,-1,0,-6,-10,-3,0,-8,-7,4,-4,-7
  • FOR i = 1 TO 4
  • FOR j = 1 TO 4
  • IF i <> j THEN
  • READ fche1(i, j), fche2(i, j), fche3(i, j), fche4(i, j)
  • END IF
  • NEXT j
  • NEXT i
  • FOR i = 1 TO 14
  • xA(i) = 200: yA(i) = 50
  • yy(i) = 2: xx(i) = 24
  • NEXT i
  • nc = 1
  • DATA 75,343,9,22,11,325,343,40,22,12,405,295,50,19,13,198,248,24,16,14
  • FOR i = 1 TO 4
  • READ xP(i), yP(i), x(i), y(i), col(i)
  • xP(i) = xP(i) - 5
  • NEXT i
  • DATA -35,-30,-25,-20,-15,-10,-5,0,5,10,15,20,25,30
  • FOR k = 1 TO 14
  • affich2(k) = -120
  • READ affich1(k)
  • NEXT k
  • col = 1
  • GOSUB dessin0
  • RETURN
  • dessin0:
  • FOR i = 1 TO 4
  • FOR k = 1 TO 14
  • LINE (xP(i), yP(i))-(xP(i) + affich1(k), yP(i) + affich2(k)), 8: LINE -(xA(nc), yA(nc)), 8
  • LINE (xP(i) + affich1(k) - 5, yP(i) + affich2(k) + 5)-(xP(i) + affich1(k), yP(i) + affich2(k)), 8
  • LINE (xP(i) + affich1(k) + 5, yP(i) + affich2(k) + 5)-(xP(i) + affich1(k), yP(i) + affich2(k)), 8
  • NEXT k
  • CIRCLE (xP(i), yP(i)), 20, col(i): PAINT (xP(i), yP(i) + 11), col(i), col(i)
  • LOCATE y(i), x(i): PRINT i
  • NEXT i
  • CIRCLE (xA(nc), yA(nc)), 15, 15: PAINT (xA(nc), yA(nc) - 6), col, 15
  • LOCATE yy(nc), xx(nc): PRINT nc
  • RETURN
  • donnees2:
  • LINE (30, 1)-(350, 490), 0, BF
  • LINE (350, 1)-(435, 337), 0, BF
  • LINE (350, 337)-(380, 385), 0, BF
  • COLOR 14: LINE (350, 380)-(370, 360): LINE (370, 360)-(365, 370): LINE (370, 360)-(360, 365)
  • COLOR 15
  • DATA 45,-10,45,-40,0,-40
  • DATA -45,10,30,-15,-20,-40
  • DATA -65,20,15,40,-35,-5
  • DATA -20,35,20,45,40,-5
  • FOR i = 1 TO 4
  • FOR j = 1 TO 4
  • IF i <> j THEN
  • READ affich3(i, j), affich4(i, j)
  • END IF
  • NEXT j
  • NEXT i
  • DATA -5,-5,-5,5,-10,3,-3,10,-6,5,4,7
  • DATA 5,-5,5,5,-10,0,-5,8,10,5,0,10
  • DATA 10,-8,13,0,-7,-8,2,-10,8,-3,8,5
  • DATA 10,-3,0,-10,-10,-3,0,-10,-8,6,-8,-5
  • FOR i = 1 TO 4
  • FOR j = 1 TO 4
  • IF i <> j THEN
  • READ fche1(i, j), fche2(i, j), fche3(i, j), fche4(i, j)
  • END IF
  • NEXT j
  • NEXT i
  • DATA 160,375,19,24,11,248,375,30,24,12,273,327,33,21,13,192,310,23,20,14
  • FOR i = 1 TO 4
  • READ xP(i), yP(i), x(i), y(i), col(i)
  • xP(i) = xP(i) - 5
  • NEXT i
  • DATA -35,-30,-25,-20,-15,-10,-5,0,5,10,15,20,25,30
  • FOR k = 1 TO 14
  • affich2(k) = -120
  • READ affich1(k)
  • NEXT k
  • GOSUB dessin01
  • DATA 7,22,4,18,9,15,9,11,11,7
  • DATA 20,12,22,9,28,9,32,12,39,7
  • DATA 41,11,41,15,46,18,43,22,25,5
  • FOR i = 1 TO 15
  • READ xx(i), yy(i)
  • yy(i) = yy(i) - 4
  • NEXT i
  • DATA 75,53,93,93,108,180,197
  • DATA 245,277,339,354,354,394,370,226
  • FOR i = 1 TO 15
  • READ xA(i)
  • xA(i) = xA(i) - 18
  • yA(i) = yy(i) * 288 / 18 - 9
  • IF i < 15 THEN
  • LOCATE yy(i), xx(i): PRINT i
  • IF i > 4 THEN
  • col = 1
  • ELSE
  • col = col(i)
  • END IF
  • CIRCLE (xA(i), yA(i)), 15, 15: PAINT (xA(i), yA(i) - 6), col, 15
  • END IF
  • NEXT i
  • RETURN
  • grille:
  • FOR i = 1 TO 50
  • x = x + 1
  • LINE (i * 10, 10)-(i * 10, 500)
  • IF x = 10 THEN
  • LINE (i * 10, 10)-(i * 10, 500), 13
  • x = 0
  • END IF
  • NEXT i
  • FOR i = 1 TO 50
  • x = x + 1
  • LINE (10, i * 10)-(500, i * 10)
  • IF x = 10 THEN
  • LINE (10, i * 10)-(500, i * 10), 13
  • x = 0
  • END IF
  • NEXT i
  • RETURN
  • texte:
  • IF UCASE$(k$) = "A" THEN
  • LOCATE 28, 1: PRINT " Tapez sur une touche"
  • f$ = INPUT$(1)
  • IF UCASE$(f$) = "S" THEN
  • k$ = ""
  • END IF
  • END IF
  • LOCATE 26, 1: PRINT " "
  • LOCATE 27, 1: PRINT " "
  • LOCATE 28, 1: PRINT " "
  • RETURN
  • fichierenregistre:
  • LINE (1, 1)-(350, 490), 0, BF
  • LINE (350, 1)-(435, 337), 0, BF
  • LINE (350, 337)-(380, 385), 0, BF
  • LOCATE 1, 1
  • OPEN "C:\Basic\Temps1" FOR RANDOM AS #1
  • itemps = 0
  • SEEK #1, 1
  • DO WHILE NOT EOF(1)
  • itemps = itemps + 1
  • GET #1, itemps, relation
  • IF relation.tps <> 0 AND relation.expliq <> "" THEN
  • PRINT "nø"; itemps; "/ tps ="; relation.tps; ".."; relation.expliq
  • END IF
  • LOOP
  • PRINT
  • PRINT " Voulez-vous enregistrer cet exemple O / N ?"
  • g$ = INPUT$(1)
  • PRINT
  • IF UCASE$(g$) = "O" THEN
  • PRINT "Inscrivez votre commentaire "
  • itemps = SEEK(1) - 2
  • PRINT itemps + 1, temps
  • itemps = itemps + 1
  • INPUT g$
  • relation.expliq = g$
  • relation.tps = temps
  • PUT #1, itemps, relation
  • GET #1, itemps, relation: PRINT "nø"; itemps; "/ tps ="; relation.tps; ".."; relation.expliq
  • CLOSE #1
  • ELSE
  • CLOSE #1
  • END IF
  • RETURN
  • fichierlit:
  • OPEN "C:\Basic\Temps1" FOR RANDOM AS #1
  • itemps = 0
  • SEEK #1, 1
  • DO WHILE NOT EOF(1)
  • itemps = itemps + 1
  • GET #1, itemps, relation
  • IF relation.tps <> 0 AND relation.expliq <> "" THEN
  • PRINT "nø"; itemps; "/ tps ="; relation.tps; ".."; relation.expliq
  • END IF
  • LOOP
  • PRINT
  • DO
  • INPUT "Lequel voulez-vous ? "; c
  • GET #1, c, relation
  • PRINT "nø "; relation.tps; "... "; relation.expliq
  • PRINT
  • PRINT "Si vous ˆtes d'accord, tapez 'O', sinon 'N'"
  • PRINT "Si vous voulez revenir ... la randomisation, tapez 'R'"
  • gg$ = INPUT$(1)
  • IF UCASE$(gg$) = "O" THEN
  • temps = relation.tps
  • OK = 1
  • temporisation = 1
  • ELSEIF UCASE$(gg$) = "R" THEN
  • temporisation = 0
  • OK = 1
  • ELSEIF UCASE$(gg$) = "N" THEN
  • OK = 0
  • END IF
  • LOOP UNTIL OK = 1
  • CLOSE #1
  • CLS
  • RETURN
  • FUNCTION maxi (n1, n2)
  • IF n1 >= n2 THEN
  • maxi = n1
  • ELSEIF n1 < n2 THEN
  • maxi = n2
  • END IF
  • END FUNCTION
  • FUNCTION mini (d1, d2)
  • IF d1 < d2 THEN
  • mini = d1
  • ELSEIF d1 >= d2 THEN
  • mini = d2
  • END IF
  • END FUNCTION