Форум программистов, компьютерный форум, киберфорум
Prolog
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/18: Рейтинг темы: голосов - 18, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 12.05.2014
Сообщений: 27
1

SWI Prolog, реализовать запрос: "Найти предприятие, у которого больше всего вакансий"

25.09.2014, 20:11. Показов 3717. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, Уважаемые Профессионалы!

Возникли сложности при реализации запроса в среде SWI Prolog.

По заданию была создана База знаний. Структура Базы знаний представлена в виде составных термов.

Prolog
1
2
3
4
5
6
7
vacancy(company('Юлмарт','менеджер',30000), education('высшее экономическое'), sex('мужской'), spec('менеджер'), lang('английский'), age(25)).
vacancy(company('Юлмарт','консультант',20000), education('высшее экономическое'), sex('женский'), spec('менеджер'), lang('английский'), age(20)).
vacancy(company('Юлмарт','программист',40000), education('высшее техническое'), sex('мужской'), spec('техник'), lang('английский'), age(21)).
vacancy(company('Ниагара','продавец',35000), education('среднее специальное'), sex('женский'), spec('менеджер'), lang('английский'), age(18)).
vacancy(company('Ниагара','кассир',20000), education('среднее'), sex('женский'), spec('менеджер'), lang('английский'), age(20)).
vacancy(company('Электросила','столяр',50000), education('среднее специальное'), sex('мужской'), spec('столяр'), lang('нет'), age(23)).
vacancy(company('Электросила','токарь',45000), education('среднее специальное'), sex('мужской'), spec('токарь'), lang('нет'), age(25)).
Запросы типа: "Найти все должности, для которых подходят соискатели со средним образованием" реализовать удалось методами сопоставления и унификации.

Prolog
1
образование(X,Y) :- vacancy(company(_,X,_), education(Y), _, _, _, _).
Необходимо реализовать запрос: "Найти предприятие, у которого больше всего вакансий".

Ни в какую не получается...

Если кто-нибудь может подкинуть идею, было бы просто замечательно.

Заранее Большое Спасибо, Уважаемые Профессионалы!
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.09.2014, 20:11
Ответы с готовыми решениями:

Для языка С++ больше всего вакансий Junior?
Может быть, этот вопрос уже звучал, надеюсь, что он не покажется очень глупым. Правда ли, что под...

Рекурсивный предикат: найти количество элементов числового списка, которые больше первого элемента [SWI-Prolog]
Помогите с задачкой (Заранее: огромное вам спасибо) Напишите рекурсивные предикат (на языке...

Найти юзера у которого больше всего привычек
Здравствуйте, зарание спасибо за совет. Есть таблицы User id, name, age 1. Ivan. ...

Найти элемент значение которого больше всего.
Дано файл F , элементы которого действительные числа . Найти элемент значение которого больше всего.

18
794 / 598 / 156
Регистрация: 07.10.2013
Сообщений: 1,327
26.09.2014, 11:01 2
Идею, пожалуйста: использовать findall, sum_list, sort, reverse
SWI-Prolog. Reference manual
Не получится - пишите.

Добавлено через 10 минут
Это была идея с ходу т.е. сразу не получится, но направление правильное.
1
0 / 0 / 0
Регистрация: 12.05.2014
Сообщений: 27
26.09.2014, 16:25  [ТС] 3
Большое спасибо)мне как раз и нужны свежие идеи)буду пробовать!
0
794 / 598 / 156
Регистрация: 07.10.2013
Сообщений: 1,327
26.09.2014, 16:53 4
Лучший ответ Сообщение было отмечено Lubov_1992 как решение

Решение

Цитата Сообщение от Lubov_1992 Посмотреть сообщение
Необходимо реализовать запрос: "Найти предприятие, у которого больше всего вакансий"
Хорошая задача для рассмотрения способов решения для подобных случаев.
Рекомендуется разобрать и пройти в отладчике и с разными данными все варианты.

Базу данных немного подрежем и перемешаем для лучшего процесса тестирования.
Кликните здесь для просмотра всего текста
Prolog
1
2
3
4
5
6
7
vacancy(company('Юлмарт','менеджер',30000), education('высшее экономическое'), sex('мужской'), spec('менеджер'), lang('английский'), age(25)).
%vacancy(company('Юлмарт','консультант',20000), education('высшее экономическое'), sex('женский'), spec('менеджер'), lang('английский'), age(20)).
%vacancy(company('Юлмарт','программист',40000), education('высшее техническое'), sex('мужской'), spec('техник'), lang('английский'), age(21)).
vacancy(company('Электросила','столяр',50000), education('среднее специальное'), sex('мужской'), spec('столяр'), lang('нет'), age(23)).
vacancy(company('Ниагара','продавец',35000), education('среднее специальное'), sex('женский'), spec('менеджер'), lang('английский'), age(18)).
vacancy(company('Электросила','токарь',45000), education('среднее специальное'), sex('мужской'), spec('токарь'), lang('нет'), age(25)).
vacancy(company('Ниагара','кассир',20000), education('среднее'), sex('женский'), spec('менеджер'), lang('английский'), age(20)).

Представлено 4 варианта решения - предикаты vacancy_maxN.
Диалект SWI-Prolog. Файл с кодом во вложении.

Вариант 1 с использованием предикатов findall, sort, member, length, reverse.
Самый "ленивый" и с максимальным использованием встроенных предикатов.
Если findall, sort, length всё же относятся к стандарту ISO,
то member и reverse уже библиотечные, т.е. может потребоваться их отдельная реализация.
Кликните здесь для просмотра всего текста
Prolog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vacancy_max1(MaxV) :-
    findall( Company,
             vacancy(company(Company, _, _), _, _, _, _, _),
             Cs0 ),
    sort(Cs0, Cs),
    findall( Qty-Company,
             ( member(Company, Cs),
               findall( Company,
                        vacancy(company(Company, _, _), _, _, _, _, _),
                        Cs1 ),
               length(Cs1, Qty)
             ),
             Vs0 ),
    sort(Vs0, Vs),
    reverse(Vs, [MaxV|_]).

Вариант 2 без использования sort, поскольку задействован setof.
Здесь же использование findall с константой и sum_list (притянул-таки его за уши)
Кликните здесь для просмотра всего текста
Prolog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vacancy_max2(MaxV) :-
    setof( Company,
             Job^Salary^Ed^Sex^Spec^Lang^Age^
             vacancy(company(Company, Job, Salary), Ed, Sex, Spec, Lang, Age),
             Cs ),
    setof( Qty-Company,
             Ns^
             ( member(Company, Cs),
               findall( 1,
                        vacancy(company(Company, _, _), _, _, _, _, _),
                        Ns ),
               sum_list(Ns, Qty)
             ),
             Vs ),
    reverse(Vs, [MaxV|_]).

Вариант 3 без findall и setof, но с forall и динамической базой данных.
Кликните здесь для просмотра всего текста
Prolog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
vacancy_max3(Qty-Company) :-
    retractall( vacancy_count(_, _) ),
    retractall( vacancy_max(_, _) ),
    forall( vacancy(company(Company, _, _), _, _, _, _, _),
            (
              ( retract( vacancy_count(Company, Count) ),
                Count1 is Count + 1,
                assertz( vacancy_count(Company, Count1) )
              ; assertz( vacancy_count(Company, 1) )
              )
            )
          ),
    forall( vacancy_count(Company1, Count1),
            (
              ( retract( vacancy_max(Company2, Count2) ),
                Count2 > Count1,
                assertz( vacancy_max(Company2, Count2) )
              ; assertz( vacancy_max(Company1, Count1) )
              )
            )
          ),
    vacancy_max(Company, Qty).

Вариант 4 без встроенного forall (реализован через отрицание),
в общем такой весь самый близкий к "чистому" использованию Пролога.
Кликните здесь для просмотра всего текста
Prolog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
vacancy_max4(Qty-Company) :-
    retractall( vacancy_count(_, _) ),
    retractall( vacancy_max(_, _) ),
    not(
        ( vacancy(company(Company, _, _), _, _, _, _, _),
          not(
              ( retract( vacancy_count(Company, Count) ),
                Count1 is Count + 1,
                asserta( vacancy_count(Company, Count1) )
              ; asserta( vacancy_count(Company, 1) )
              )
          )
        )
    ),
    not(
        ( vacancy_count(Company1, Count1),
          not(
              ( retract( vacancy_max(Company2, Count2) ),
                Count2 > Count1,
                assertz( vacancy_max(Company2, Count2) )
              ; assertz( vacancy_max(Company1, Count1) )
              )
          )
        )
    ),
    vacancy_max(Company, Qty).

not не является префиксным оператором, что для желающих может быть исправлено
применением op(900, fy, not), тогда скобок поменьше или же использовать \+ стандарта ISO.

Кроме того, если в вариантах 1 и 2, при равных количествах вакансий,
имеет значение сортировка по имени (здесь в обратном порядке),
то варианты 3 и 4 в том же случае отличаются порядком встречи фактов (последним/первым)
при переборе фактов базы данных.
Вложения
Тип файла: rar vacancy_max.rar (2.1 Кб, 26 просмотров)
1
0 / 0 / 0
Регистрация: 12.05.2014
Сообщений: 27
26.09.2014, 17:22  [ТС] 5
Вот это да!Prolog просто неисчерпаемый язык)аж 4 варианта реализации!а я только начала изучать синтаксис findall)

Спасибо Вам огромное за помощь! Очень признательна!а то уж совсем отчаялась найти решение...

Сейчас же это всё и проанализирую!надо теперь осознать)
0
794 / 598 / 156
Регистрация: 07.10.2013
Сообщений: 1,327
26.09.2014, 17:31 6
Ну, это не сразу все варианты родились...
Просто решить задачу для отмазки, чтобы спихнуть чей-то зачет, не сильно интересно.
А так и для форума польза и для себя...
Собственно, обобщение и поиск разных вариантов, это и есть хорошая практика программирования, на любом языке.
0
0 / 0 / 0
Регистрация: 12.05.2014
Сообщений: 27
26.09.2014, 17:42  [ТС] 7
Если совсем не думать, то и мозг рискует засохнуть... а Вы добро творите)свежие идеи, мысли, варианты. действительно, и другим пригодится ещё. Prolog может и не самый распространённый язык программирования, но мозг развивает значительно! это не просто форум, а палочка-выручалочка)

Надо бы освоить работу со списками в Prolog. пропустила это базовое понятие в процессе обучения.
0
794 / 598 / 156
Регистрация: 07.10.2013
Сообщений: 1,327
26.09.2014, 17:47 8
SWI-Prolog проверить что символы совпадают одинаковое кол-во раз
В догонку для ознакомления с Прологом...
1
0 / 0 / 0
Регистрация: 12.05.2014
Сообщений: 27
26.09.2014, 18:09  [ТС] 9
Пролог всё может в руках умелого программиста)спасибо Вам огромное!обязательно изучу)вообще надо по форуму посмотреть.зачастую у людей очень интересные задачи!
0
794 / 598 / 156
Регистрация: 07.10.2013
Сообщений: 1,327
26.09.2014, 18:24 10
Этт, точно.
Я одно время отчаялся, ушёл с форума... всё одно и тоже хотят, поискать и/или модифицировать под свою задачу некоторым просто влом...
Сейчас, вроде вернулся, бывает и из простой задачи можно чего-нибудь сотворить, а то встречаются иногда и немного новые, ну, или почти новые.
Читать классику никто не хочет долго, так уже рекомендую краткие курсы, вот неплохой, хоть и звучит страшно:
Бессмертный И.А. Искусственный интеллект PDF. Учебное пособие. - СПб: СПбГУ ИТМО, 2010.
0
0 / 0 / 0
Регистрация: 12.05.2014
Сообщений: 27
26.09.2014, 18:35  [ТС] 11
Кстати да...литература в этом деле просто бесценна.примеров много хороших!в Интернете в основном англоязычная литература, а то и немецкие сайты проглядывают.у меня только книга Братко была в наличии.пополним библиотеку!спасибо за совет,надо скачать)
0
794 / 598 / 156
Регистрация: 07.10.2013
Сообщений: 1,327
26.09.2014, 18:48 12
Ну, раз уж завели беседу, то вот ещё пример решения задачи
Задача про авиационное подразделение
Примечателен тем, что можно и в 12 строчек реализовать, а можно обобщить и получить еще и "безплатные конфеты".
В этом случае не только определить специальности, но и заодно все увлечения, было интересно...
1
0 / 0 / 0
Регистрация: 12.05.2014
Сообщений: 27
27.09.2014, 17:49  [ТС] 13
Ооо...да тут неограниченный источник знаний)спасибо,будем изучать!главное-последовательность и усидчивость...)

Добавлено через 20 часов 11 минут
Кажется,ещё с одной проблемой столкнулась)создаю интерфейс к данной Базе Знаний.все запросы работают,а вот этот не хочет.он этот запрос выполнять не хочет.с XPCE поссорились.не хочет он в одно поле выводить и количество вакансий и имя компании.вроде,и понимает,чего от него хотят,а сделать не может,не положено)

Тут и входных параметров нет, выдавай да выдавай,ан нет!буду думать)

Prolog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
interface :-
      new(Dialog, dialog('Биржа труда')),
      send_list(Dialog, append, [
           new(Education, menu('Образование:', cycle)),
           new(Spec, menu('Специальность:', cycle)),
           new(Sex, new(Sex, menu('Пол:'))),
           new(Salary, int_item('Доход:', low := 5000, high := 60000)),
           new(Lang, menu('Знание иностранных языков:', cycle)),
           new(MyList, list_browser),
           button('1: образование', message(@prolog,
                  output, MyList, Education?selection)),
           button('2: специальность', message(@prolog,
                  output1, MyList, Spec?selection)),
           button('3: пол и доход', message(@prolog,
                  output2, MyList, Sex?selection, Salary?selection)),
           button('4: иностранный язык', message(@prolog,
                  output3, MyList, Lang?selection)),
           button('5: > вакансий', message(@prolog,
                  output4, MyList)),
           button('Очистить', message(MyList, clear)),
           button('Выход', message(Dialog, destroy))
           ]),
      send_list(Education, append, ['','высшее экономическое','высшее техническое','среднее','среднее специальное']),
      send_list(Spec, append, ['','менеджер','токарь','столяр','техник']),
      send_list(Lang, append, ['','нет','английский','немецкий','французский']),
      send_list(Sex, append, ['мужской', 'женский']),
      send(MyList, alignment, center),
      send(MyList, size, size(50,20)),
      send(Dialog, open(point(100,400))).
 
output4(MyList) :-
        send(MyList, clear),
        vacancy_max1(MaxV),
        send(MyList, append, MaxV),
        fail.
Хотя, если подправить Ваш 3-й вариант решения он выдаёт свободно название компании.эх,учиться надо!)

Может,ещё пара идей найдётся)по GUI информации тоже хватает.хотя,англоязычная и преобладает.буду пока что углубляться в чтение англоязычной литературы.
0
794 / 598 / 156
Регистрация: 07.10.2013
Сообщений: 1,327
28.09.2014, 13:24 14
Наверное MaxV здесь структура, поэтому и не хочет. В моих примерах '-' используется как структура -(Arg1,Arg2), просто удобно, когда выдаёт в виде Arg1-Arg2, для сортировки в том числе. Надо склеить перед выдачей результата.

Добавлено через 16 минут
Ну конечно надо преобразовать, если список вакансий:
Кликните здесь для просмотра всего текста
Prolog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vacancy_max_list(Vs1) :-
    findall( Company,
             vacancy(company(Company, _, _), _, _, _, _, _),
             Cs0 ),
    sort(Cs0, Cs),
    findall( Qty-Company,
             ( member(Company, Cs),
               findall( Company,
                        vacancy(company(Company, _, _), _, _, _, _, _),
                        Cs1 ),
               length(Cs1, Qty)
             ),
             Vs0 ),
    sort(Vs0, Vs),
    reverse(Vs, Vs1).

Склеить тоже не помешает, например:
Кликните здесь для просмотра всего текста
Prolog
1
2
3
4
5
6
7
output4(MyList) :-
        send(MyList, clear),
        vacancy_max_list(Vs),
        member(Qty-Company, Vs),
        atomic_list_concat([Company, ' (', Qty, ')'], X),
        send(MyList, append, X),
        fail.


Добавлено через 4 минуты
Или, собственно, только для всех максимальных:
Кликните здесь для просмотра всего текста
Prolog
1
2
3
4
5
6
7
8
output4(MyList) :-
        send(MyList, clear),
        vacancy_max3(_),
        vacancy_max(_, Qty),
        vacancy_count(Company, Qty),
        atomic_list_concat([Company, ' (', Qty, ')'], X),
        send(MyList, append, X),
        fail.
1
0 / 0 / 0
Регистрация: 12.05.2014
Сообщений: 27
28.09.2014, 13:33  [ТС] 15
Вы,наверное,просто Волшебник)сколько у Пролога встроенных предикатов...вот мозг у меня точно склеился уже.спасибо Вам огромное)мой личный тезаурус пополнен ещё и методами склеивания в Пролог)сколько же надо времени, чтобы поднатореть в этом деле...удобно, кстати, когда выдаёт вместе с количеством заявок.а вместе с графическим интерфейсом вообще конфетка!
0
794 / 598 / 156
Регистрация: 07.10.2013
Сообщений: 1,327
28.09.2014, 13:46 16
Взаимно, т.к. я c XPCE вообще не работаю тут пришлось попробовать попрактиковался заодно...

Добавлено через 6 минут
Понятное дело, у меня всегда SWI-Prolog. Reference manual на взводе, даже не стараюсь всё запоминать, главное направление и знать что есть нечто подобное.
У SWI-Prolog хорошая онлайн документация. Если с языком нет проблем, то там шерстить много чего можно, да и загрузить PDF-ок...
0
0 / 0 / 0
Регистрация: 12.05.2014
Сообщений: 27
28.09.2014, 13:47  [ТС] 17
Верно говорят: талантливый человек талантлив во всём)
0
794 / 598 / 156
Регистрация: 07.10.2013
Сообщений: 1,327
28.09.2014, 13:50 18
Ну, не надо уж лести... и тут надо добавить что-нибудь бубняще-старческое про опыт и т.п.
0
0 / 0 / 0
Регистрация: 12.05.2014
Сообщений: 27
28.09.2014, 14:08  [ТС] 19
Не обижайтесь, пожалуйста. я правда благодарна)спасибо ещё раз!)кстати,книг-то много накачала на компьютер,а искать нужное ещё надо научиться.дааа,опыт-это вообще что-то бесценное.только чтобы его набрать,надо постараться.
0
28.09.2014, 14:08
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.09.2014, 14:08
Помогаю со студенческими работами здесь

Найти элемент, в значении которого больше всего разрядов
Дана матрица A(n×n) многоразрядных целых чисел. Найти номер строки и номер столбца, на пересечении...

Запрос SWI prolog
Добрый вечер! подскажите пожалуйста, есть такая задачка, кто где живет живет('Зебра', X):-...

Реализовать запросы в SWI Prolog
Реализовать запросы в SWI Prolog Типы запросов: 1. Найти марку автомобиля, которую продает больше...

Определить, какой элемент списка встречается в нем чаще всего (Turbo/SWI Prolog)
Определить, какой элемент списка встречается в нем чаще всего.

Найти в матрице число, в двоичном представлении которого больше всего единиц
Условие. Размерности массивов вводить с клавиатуры. Исходные данные и результаты выводить на экран...

Вывести предприятие, получившее больше всего кредитов
вывести предприятие, получившее больше всего кредитов. SELECT ., Count(Договор.) AS FROM ...

Найти натуральное число из заданного интервала, в двоичном представлении которого больше всего единиц
Указать натуральное число из заданного интервала, в двоичном представлении которого больше всего...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru