Я реализую генератор случайных CSP для проведения сравнительного тестирования двух разных алгоритмов согласования дуги (AC3 и AC2001). Экземпляры генерируются с параметрами числа переменных, размером 8 областей для всех переменных), количеством ограничений и числом пар значений, отвергаемых каждым ограничением (одинаково для всех ограничений).Генерация случайных экземпляров двоичных проблем с ограничением ограничений
В моей реализации строятся переменные (структура с двумя полями, именем и доменом (список)), ограничения 8структуры с двумя полями, задействованные переменные и функция ограничения)). он создает хеш-таблицу, которая имеет переменные, участвующие в каждом ограничении в качестве ключей, а как значения - список пар, отклоненных указанным ограничением. При использовании каждое ограничение проверяет, содержатся ли указанные значения в переменных в списке отклоненных значений.
Эта реализация «работает», но очень мало генерируемых экземпляров нуждаются в дуговом сокращении, поэтому они в большинстве случаев бесполезны для целей тестирования. Вот код:
; This function generates the complete list of variables for the problem
(defun crea-lista-variables (nvars tdom p-v)
(loop for i from 0 to (1- nvars) collect
(crea-variable :nombre i
:dominio (crea-dominio-nuevo tdom p-v nil))))
; This function creates a variable's domain, without repetitions. It takes it's
; values from a list of possible values for the problem
(defun crea-dominio-nuevo (tdom p-v dominio)
(let ((candidato (nth (random (1- (length p-v))) p-v)))
(cond ((= tdom 0) dominio)
((not (pertenece candidato dominio))
(crea-dominio-nuevo (- tdom 1) p-v
(append dominio (list candidato))))
(t (crea-dominio-nuevo tdom p-v dominio)))))
Эта функция создает restriccions и он отклонил значения
(defun crea-lista-restricciones (nrest npares tdom p-p p-v
restricciones rechazados)
(let* ((variables (nth (random (1- (length p-p))) p-p))
(rest (crea-restriccion :variables variables
:funcion #'(lambda (x y &optional (z nil))
(not (pertenece (list x y)
z))))))
(cond ((= nrest 0) restricciones)
((null (gethash variables rechazados))
(crea-rechazados npares tdom variables p-v rechazados)
(crea-lista-restricciones (1- nrest) npares tdom p-p
p-v (append restricciones (list rest))
rechazados))
(t (crea-lista-restricciones nrest npares tdom p-p
p-v restricciones rechazados)))))
Эта функция создает отклоненные значения хэш-таблицы
(defun crea-rechazados (numpares tamdom variables posibles-valores rechazados)
(let* ((valor1 (nth (random (1- (length posibles-valores)))
posibles-valores))
(valor2 (nth (random (1- (length posibles-valores)))
posibles-valores))
(candidato (list valor1 valor2))
(lista (gethash variables rechazados)))
(cond ((= numpares 0) rechazados)
((not (pertenece candidato lista))
(setf (gethash variables rechazados)
(append lista (list candidato)))
(crea-rechazados (1- numpares) tamdom variables
posibles-valores rechazados))
(t (crea-rechazados numpares tamdom variables
posibles-valores rechazados)))))
И главная функция, которая создает глобальные параметры для решателей, использующих
(defun genera-problema (numvars tamdom numrest numpares)
(cond ((< numvars 2)
(format t "~&Error: Debe haber al menos 2 variables"))
((< tamdom 2)
(format t "~&Error: Los dominios deben tener al menos dos elementos"))
((or (< numrest 0) (> numrest (/ (* numvars (- numvars 1)) 2)))
(format t "~&Error: numero de restricciones incorrecto"))
((or (< numpares 1) (> numpares (- (* tamdom tamdom) 1)))
(format t "~&Error: numero de pares incorrecto"))
(t (let ((posibles-valores (loop for i from 0
to (1- (+ tamdom tamdom))
collect i))
(posibles-pares (loop for i from 0 to (- numvars 2) append
(loop for j from (+ i 1)
to (1- numvars)
collect (list i j)))))
(defparameter *RECHAZADOS*
(make-hash-table :test #'equalp))
(defparameter *VARIABLES-AC3*
(crea-lista-variables numvars tamdom posibles-valores))
(defparameter *VARIABLES-AC2001*
(loop for variable in *VARIABLES-AC3*
collect (crea-variable :nombre (psr-var-nombre var)
:dominio (copia-lista
(psr-var-dominio var)))))
(defparameter *RESTRICCIONES*
(crea-lista-restricciones numrest numpares tamdom
posibles-pares posibles-valores
nil *RECHAZADOS*))
(defparameter *ARCOS-AC3* 0)
(defparameter *ARCOS-AC2001* 0)))))
Функция «pertenece» проверяет, находится ли элемент в списке Надеюсь, это понятно даже с испанскими именами. Если это не я могу перевести его полностью.
Итак, мои отвратительные навыки кодирования lisp в сторону, есть ли какая-либо ошибка, которую я могу исправить или улучшить, которую я могу сделать для того, чтобы экземпляры сгенерировали более высокое качество?
Я не смотрел ваш код. 1. Можете ли вы лучше описать, как вы создаете свои ограничения? На сколько переменных они варьируются, каждый? 2. Какие комбинации параметров вы пытались? – ziggystar