在prolog中循环有向图

时间:2016-11-21 14:35:02

标签: prolog

我在prolog中创建了一个程序,它应该给我一个循环中两个站点之间的路由。当我例如询问s3和s4之间的路线时,它给了我两条正确的路线[s3,s4]和[s3,s2,s1,s6,s5,s4],但它也给了我一个解决方案我不会# 39;不要。它是[s3,s4,s5,s6,s1,s2,s3,s4]。不可能多次访问一条路线中的一个站点。我尝试使用member命令阻止这一点,但它似乎并不总是有效。我该如何解决这个问题?

以下是代码:

#-*- coding: utf-8 -*-

from django.db import models
from django.forms import ModelForm

# Sexe choice

CHOIX_SEXE = (
('M', 'Mâle'),
('F','Femelle'),
)

CHOIX_PAYS = (
('AFG','Afghanistan'),
('AF','Afghanistan'),
('ZA','Afrique du Sud'),
('AL','Albanie'),
('DZ','Algérie'),
('DE','Allemagne'),
('AD','Andorre'),
('AO','Angola'),
('AI','Anguilla'),
('AQ','Antarctique'),
('AG','Antigua-et-Barbuda'),
('AN','Antilles néerlandaises'),
('SA','Arabie saoudite'),
('AR','Argentine'),
('AM','Arménie'),
('AW','Aruba'),
('AU','Australie'),
('AT','Autriche'),
('AZ','Azerbaïdjan'),
('BJ','Bénin'),
('BS','Bahamas'),
('BH','Bahreïn'),
('BD','Bangladesh'),
('BB','Barbade'),
('PW','Belau'),
('BE','Belgique'),
('BZ','Belize'),
('BM','Bermudes'),
('BT','Bhoutan'),
('BY','Biélorussie'),
('MM','Birmanie'),
('BO','Bolivie'),
('BA','Bosnie-Herzégovine'),
('BW','Botswana'),
('BR','Brésil'),
('BN','Brunei'),
('BG','Bulgarie'),
('BF','Burkina Faso'),
('CA','Canada'),
('CV','Cap-Vert'),
('CL','Chili'),
('CN','Chine'),
('CY','Chypre'),
('CO','Colombie'),
('KM','Comores'),
('CG','Congo'),
('KP','Corée du Nord'),
('KR','Corée du Sud'),
('CR','Costa Rica'),
('HR','Croatie'),
('CU','Cuba'),
('DK','Danemark'),
('DJ','Djibouti'),
('DM','Dominique'),
('EG','Égypte'),
('AE','Émirats arabes unis'),
('EC','Équateur'),
('ER','Érythrée'),
('ES','Espagne'),
('EE','Estonie'),
('US','États-Unis'),
('ET','Éthiopie'),
('FI','Finlande'),
('FR','France'),
('GE','Géorgie'),
('GA','Gabon'),
('GM','Gambie'),
('GH','Ghana'),
('GI','Gibraltar'),
('GR','Grèce'),
('GD','Grenade'),
('GL','Groenland'),
('GP','Guadeloupe'),
('GU','Guam'),
('GT','Guatemala'),
('GN','Guinée'),
('GQ','Guinée équatoriale'),
('GW','Guinée-Bissao'),
('GY','Guyana'),
('GF','Guyane française'),
('HT','Haïti'),
('HN','Honduras'),
('HK','Hong Kong'),
('HU','Hongrie'),
('BV','Ile Bouvet'),
('CX','Ile Christmas'),
('NF','Ile Norfolk'),
('KY','Iles Cayman'),
('CK','Iles Cook'),
('FO','Iles Féroé'),
('FK','Iles Falkland'),
('FJ','Iles Fidji'),
('GS','Iles Géorgie du Sud et Sandwich du Sud'),
('HM','Iles Heard et McDonald'),
('MH','Iles Marshall'),
('PN','Iles Pitcairn'),
('SB','Iles Salomon'),
('SJ','Iles Svalbard et Jan Mayen'),
('TC','Iles Turks-et-Caicos'),
('VI','Iles Vierges américaines'),
('VG','Iles Vierges britanniques'),
('CC','Iles des Cocos (Keeling),'),
('UM','Iles mineures éloignées des États-Unis'),
('IN','Inde'),
('ID','Indonésie'),
('IR','Iran'),
('IQ','Iraq'),
('IE','Irlande'),
('IS','Islande'),
('IL','Israël'),
('IT','Italie'),
('JM','Jamaïque'),
('JP','Japon'),
('JO','Jordanie'),
('KZ','Kazakhstan'),
('KE','Kenya'),
('KG','Kirghizistan'),
('KI','Kiribati'),
('KW','Koweït'),
('LA','Laos'),
('LS','Lesotho'),
('LV','Lettonie'),
('LB','Liban'),
('LR','Liberia'),
('LY','Libye'),
('LI','Liechtenstein'),
('LT','Lituanie'),
('LU','Luxembourg'),
('MO','Macao'),
('MG','Madagascar'),
('MY','Malaisie'),
('MW','Malawi'),
('MV','Maldives'),
('ML','Mali'),
('MT','Malte'),
('MP','Mariannes du Nord'),
('MA','Maroc'),
('MQ','Martinique'),
('MU','Maurice'),
('MR','Mauritanie'),
('YT','Mayotte'),
('MX','Mexique'),
('FM','Micronésie'),
('MD','Moldavie'),
('MC','Monaco'),
('MN','Mongolie'),
('MS','Montserrat'),
('MZ','Mozambique'),
('NP','Népal'),
('NA','Namibie'),
('NR','Nauru'),
('NI','Nicaragua'),
('NE','Niger'),
('NG','Nigeria'),
('NU','Nioué'),
('NO','Norvège'),
('NC','Nouvelle-Calédonie'),
('NZ','Nouvelle-Zélande'),
('OM','Oman'),
('UG','Ouganda'),
('UZ','Ouzbékistan'),
('PE','Pérou'),
('PK','Pakistan'),
('PA','Panama'),
('PG','Papouasie-Nouvelle-Guinée'),
('PY','Paraguay'),
('NL','Pays-Bas'),
('PH','Philippines'),
('PL','Pologne'),
('PF','Polynésie française'),
('PR','Porto Rico'),
('PT','Portugal'),
('QA','Qatar'),
('CF','République centrafricaine'),
('CD','République démocratique du Congo'),
('DO','République dominicaine'),
('CZ','République tchèque'),
('RE','Réunion'),
('RO','Roumanie'),
('GB','Royaume-Uni'),
('RU','Russie'),
('RW','Rwanda'),
('SN','Sénégal'),
('EH','Sahara occidental'),
('KN','Saint-Christophe-et-Niévès'),
('SM','Saint-Marin'),
('PM','Saint-Pierre-et-Miquelon'),
('VA','Saint-Siège' ),
('VC','Saint-Vincent-et-les-Grenadines'),
('SH','Sainte-Hélène'),
('LC','Sainte-Lucie'),
('SV','Salvador'),
('WS','Samoa'),
('AS','Samoa américaines'),
('ST','Sao Tomé-et-Principe'),
('SC','Seychelles'),
('SL','Sierra Leone'),
('SG','Singapour'),
('SI','Slovénie'),
('SK','Slovaquie'),
('SO','Somalie'),
('SD','Soudan'),
('LK','Sri Lanka'),
('SE','Suède'),
('CH','Suisse'),
('SR','Suriname'),
('SZ','Swaziland'),
('SY','Syrie'),
('TW','Taïwan'),
('TJ','Tadjikistan'),
('TZ','Tanzanie'),
('TD','Tchad'),
('TF','Terres australes françaises'),
('IO','Territoire britannique Océan Indien'),
('TH','Thaïlande'),
('TL','Timor Oriental'),
('TG','Togo'),
('TK','Tokélaou'),
('TO','Tonga'),
('TT','Trinité-et-Tobago'),
('TN','Tunisie'),
('TM','Turkménistan'),
('TR','Turquie'),
('TV','Tuvalu'),
('UA','Ukraine'),
('UY','Uruguay'),
('VU','Vanuatu'),
('VE','Venezuela'),
('VN','Viêt Nam'),
('WF','Wallis-et-Futuna'),
('YE','Yémen'),
('YU','Yougoslavie'),
('ZM','Zambie'),
('ZW','Zimbabwe'),
('MK','ex-République yougoslave de Macédoine'),
)

# Create my Form model

class BirthCertificate(models.Model) :

    rowid = models.AutoField(primary_key=True)
    nom = models.CharField('Nom', max_length=30, null=False)   # Lastname
    prenom = models.CharField('Prénom', max_length=30, null = False)   # Firstname
    sexe = models.CharField('Sexe', max_length=1, choices = CHOIX_SEXE)  # Choice between 'M' or 'F'
    birthday = models.DateField('Date de naissance', null=False)
    birthhour = models.TimeField('heure de naissance', null=False)
    birthcity = models.CharField('Ville de naissance', max_length = 30, null=False)
    birthcountry = models.CharField('Pays de naissance', max_length=2, choices= CHOIX_PAYS)

    nom_pere = models.CharField('Nom père', max_length=30, null=False)
    prenom_pere = models.CharField('Prénom père', max_length=30, null=False)
    birthday_pere = models.DateField('Date de naissance du père', null=False)
    birthcity_pere = models.CharField('Ville de naissance du père', max_length=30, null=False)
    birthcountry_pere = models.CharField('Pays de naissance du père', max_length=2, choices= CHOIX_PAYS)
    job_pere = models.CharField('Profession du père', max_length=30, null=False)
    adress_pere = models.CharField('Adresse du père', max_length=40, null=False)
    ville_pere = models.CharField('Ville du père', max_length=30, null=False)
    zip_pere = models.IntegerField('Code Postal du père', null=False)
    pays_pere = models.CharField('Pays du père', max_length=2, choices= CHOIX_PAYS)

    nom_mere = models.CharField('Nom mère', max_length=30, null=False)
    prenom_mere = models.CharField('Prénom mère', max_length=30, null=False)
    birthday_mere = models.DateField('Date de naissance de la mère', null=False)
    birthcity_mere = models.CharField('Ville de naissance de la mère', max_length=30, null=False)
    birthcountry_mere = models.CharField('Pays de naissance de la mère', max_length=2, choices= CHOIX_PAYS)
    job_mere = models.CharField('Profession de la mère', max_length=30, null=False)
    adress_mere = models.CharField('Adresse de la mère', max_length=40, null=False)
    ville_mere = models.CharField('Ville de la mère', max_length=30, null=False)
    zip_mere = models.IntegerField('Code Postal de la mère', null=False)
    pays_mere = models.CharField('Pays de la mère', max_length=2, choices= CHOIX_PAYS)

    nom_temoin1 = models.CharField('Nom témoin n°1', max_length=30, null=False)
    prenom_temoin1 = models.CharField('Prénom témoin n°1', max_length=30, null=False)
    birthday_temoin1 = models.DateField('Date de naissance du témoin n°1', null=False)
    birthcity_temoin1 = models.CharField('Ville de naissance du témoin n°1', max_length=30, null=False)

    nom_temoin2 = models.CharField('Nom témoin n°2', max_length=30, null=False)
    prenom_temoin2 = models.CharField('Prénom témoin n°2', max_length=30, null=False)
    birthday_temoin2 = models.DateField('Date de naissance du témoin n°2', null=False)
    birthcity_temoin2 = models.CharField('Ville de naissance du témoin n°2', max_length=30, null=False)

    def __str__(self):
        return self.nom
        return self.prenom
        return self.sexe

enter image description here

提前致谢!

1 个答案:

答案 0 :(得分:1)

这是Prolog中的经典错误。您得到了这个额外的答案,因为route1(或route2)的第三条规则与第二条规则匹配的超集匹配,这不是您想要的。

例如,如果我们只看:

route1(X,Y,_,[X,Y]) :- direction1(X,Y).
route1(X,Y,L,R) :- direction1(X,Z), \+member(Z,L), route1(Z,Y,[Z|L],RZ), R=[X|RZ].

然后我们看到,如果XY与第一条规则匹配,那么它们也会匹配第二条规则,从而导致您的问题。实际上,我们希望第二条规则仅在第一条规则失败时应用(即如果XY之间没有路径,并且我们必须从{{1}开始经过其他点}})。

因此,我们可以通过这些简单的更改解决此问题(在删除对Z的调用之后):

route1(X,Y,R) :- 
    route1(X,Y,[],R).
route1(X,Y,_,[X,Y]) :- 
    direction1(X,Y).
route1(X,Y,L,R) :- 
    \+ direction1(X,Y), 
    direction1(X,Z), 
    route1(Z,Y,[Z|L],RZ), 
    R=[X|RZ].

route2(X,Y,R) :- 
    route2(X,Y,[],R).
route2(X,Y,_,[X,Y]) :- 
    direction2(X,Y).
route2(X,Y,L,R) :- 
    \+ direction2(X,Y), 
    direction2(X,Z), 
    route2(Z,Y,[Z|L],RZ), 
    R=[X|RZ].

如果两行以粗体显示,我们说只有在memberX之间没有直接路径时,这些规则才适用。

相关问题